0

我在我的一个函数中使用 socket.io 侦听器来侦听“失败者”事件,以告诉客户端另一个客户端赢了。但是,我不能在 socket.on 函数中使用“this”关键字来谈论我的客户端,因为 this 指的是套接字本身。我会以错误的方式解决这个问题吗?或者可以通过其他方式访问客户端对象,比如超级?

            socket.on('loser', function() {
                //Remove all current objects then restart the game.
                //THIS PART DOESN'T WORK, SINCE 'THIS' NO LONGER REFERS TO 
                //THE GAME OBJECT, BUT INSTEAD REFERENCES THE SOCKET LISTENER.
                for(var i = 0; i < this.board.objects.length; i++)
                {
                    this.board.remove(this.board.objects[i]);
                }
                //WORKS AS EXPECTED FROM HERE ON...
                Game.setBoard(1, new TitleScreen(gameType,
                        "Loser!",
                         "Press Space to Play Again", 
                     playGame));                    
            });
4

3 回答 3

3

函数不携带有关引用它们的对象的任何信息,您可以.bind()在传递函数之前将其绑定到对象:

socket.on('loser', function() {
    //Remove all current objects then restart the game.
    //THIS PART DOESN'T WORK, SINCE 'THIS' NO LONGER REFERS TO 
    //THE GAME OBJECT, BUT INSTEAD REFERENCES THE SOCKET LISTENER.
    for (var i = 0; i < this.board.objects.length; i++) {
        this.board.remove(this.board.objects[i]);
    }
    //WORKS AS EXPECTED FROM HERE ON...
    Game.setBoard(1, new TitleScreen(gameType, "Loser!", "Press Space to Play Again",
    playGame));
}.bind(this));
于 2012-12-09T18:12:16.623 回答
1

在浏览器领域,执行此操作的常用方法是var that = this;在输入函数之前设置一个变量,然后使用that

但是,ECMAScript5 引入了bind(),它可以让你防止价值this丢失。当然,在 NodeJS 中使用它是安全的(不像在浏览器领域,您必须支持旧版浏览器)。

socket.on('loser', (function() {
    //Remove all current objects then restart the game.
    for (var i = 0; i < this.board.objects.length; i++) {
        this.board.remove(this.board.objects[i]);
    }
    //WORKS AS EXPECTED FROM HERE ON...
    Game.setBoard(1, new TitleScreen(gameType, "Loser!", "Press Space to Play Again", playGame));
}).bind(this));​

有关详细信息,请参阅https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

于 2012-12-09T18:12:49.510 回答
0

这样的事情有什么问题?

var self = this;
socket.on('loser', (function() {
    //Remove all current objects then restart the game.
    for (var i = 0; i < self.board.objects.length; i++) {
        self.board.remove(self.board.objects[i]);
    }
}
于 2012-12-09T22:18:09.013 回答