0

問題を説明するためにコードを単純化しました。

function SnakeGame ()
{
    this.snakeDirection         = 'right';

    this.Init = function ()
    {
        window.addEventListener('keydown', this.keyboardInput, false);
    }

    this.keyboardInput = function (event, SnakeGameObject)
    {
        console.log(SnakeGameObject); //Error since I can't pass this variable...
        console.log(event.keyCode); //Works
    }
}

this.keyboardInput 関数内で、変数 this.snakeDirection を変更しようとしました。問題は、SnakeGame オブジェクトへの参照を取得できないことです。これは、keyboardInput 関数内ではウィンドウを参照します。ウィンドウを参照する理由は理解できますが、解決策が思いつきません...

完全なコードはここで見ることができます: http://eriknijland.nl/stackoverflow/snake_event_listener/

4

3 に答える 3

2

ミスリルの答えは正しいですが、メソッドをイベント コールバックとして使用しないことをお勧めします。理由: a) それらは公開されているため、コードが大きくなると非常に簡単に却下される可能性があり、b) 一般にアクセス可能です:

var snakeInstance = new SnakeGame();
var otherObject = new SomethingElse();
snakeInstance.keyboardInput.apply(otherObject,[]);//invokes method, uses self, though self !== otherObject, but snakeInstance.

だから私は閉鎖を使用します:

function SnakeGame()
{
    this.snakeDirection = 'right';
    var keyBoardInput = (function(that)
    {
        return function(e)
        {
            console.log(that);
            console.log(e.keyCode);
        }
    })(this);
    this.Init = function()
    {
        document.body.addEventListener('keydown',keyboardInput,false);
    }
}

また、コードは完全に X ブラウザーと互換性があるわけではないことに注意してください (addEventListener && attachEvent?)。

于 2012-09-01T21:47:02.980 に答える
1

ES5 をターゲットにしている場合 (そうすべきです)、次のように記述します。

window.addEventListener('keydown', this.keyboardInput.bind(this), false);

これにより、コールバックが常にthisそのコンテキストとして呼び出されることが保証されます。

于 2012-09-01T21:52:15.940 に答える
0

これを試して:

function SnakeGame ()
{
    var self = this;
    this.snakeDirection         = 'right';

    this.Init = function ()
    {
        window.addEventListener('keydown', this.keyboardInput, false);
    }

    this.keyboardInput = function (event)
    {
        console.log(self); 
        console.log(event.keyCode); //Works
    }
}
于 2012-09-01T21:33:07.507 に答える