【问题标题】:Using this keyword within Socket.io on function在 Socket.io on function 中使用 this 关键字
【发布时间】:2012-12-09 18:10:08
【问题描述】:

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

【问题讨论】:

    标签: javascript oop node.js socket.io this


    【解决方案1】:

    函数不携带任何关于引用它们的对象的信息,您可以在传递函数之前使用.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));
    

    【讨论】:

    • 请务必注意,IE 8 不支持 Function.bind,这在许多人口统计数据中仍然很普遍。不过,有一些很好的方法可以添加它,for example, these
    【解决方案2】:

    在浏览器领域中,执行此操作的常用方法是在输入函数之前设置一个类似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

    【讨论】:

      【解决方案3】:

      这样有什么问题吗?

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-05
        • 2016-06-05
        • 1970-01-01
        • 2018-03-24
        • 2010-10-09
        • 2011-10-10
        相关资源
        最近更新 更多