简体   繁体   中英

Using this keyword within Socket.io on function

I'm using a socket.io listener within one of my functions to listen for a "loser" event to tell the client that the other client won. However, I can't use the "this" keyword to talk about my client while inside the socket.on function as this refers to the socket itself. Am I going about this the wrong way? Or can access the client object some other way, like super?

            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));                    
            });

Functions don't carry any information about the objects that reference them, you can use .bind() to bind the function to your object before you pass it:

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));

In browser-land the common way to do this is to set a variable like var that = this; before you enter the function, and then use that instead.

However, ECMAScript5 brought in bind() , which allows you to prevent the value of this being lost. In NodeJS of course, it's safe to use this (unlike in browser-land, where you have to support older browsers).

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));​

For more info, see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

Whats wrong with something like this?

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]);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM