在node.js中,这工作得很好,但是在浏览器中似乎很虚弱。每当我从Core.handleLogin调用Events时,this中的Core.handleLogin指向一个Socket(socket.io)。是否可以像在node.js中那样,让JavaScript将原型的默认this设置为其父对象?

核心库

/*
 *  CLIENT.
 *  THIS IS THE CORE/PARENT MODULE OF THE GAME.
 */

(function(){
function Core(client){
    //game modules
    this.client = client;

    //load game modules
    this.Events = new Game.Events(this, client);
    this.Map = new Game.Map(this);
    this.Player = new Game.Player(this);
    this.Canvas = new Game.Canvas(this, document.getElementById('game'));
}

Core.prototype.handleLogin = function(data){
    console.log(this); <------------------------------ I WANT THIS TO THE CORE OBJECT

    if(data){
        this.Player.username = data.username;
        this.Player.rights = data.rights;

        console.log('Logged in.');
    }else{
        console.log('Failed login.');
    }
}

Game.Core = Core;
})();


活动库

/*
 *  CLIENT
 */

(function(){
function Events(Core,client){
    this.Core = Core;
    this.client = client;

    client.on('connect', function(){
        console.log('Connected to the server.');

        client.emit('login', Core.getCookie('session'));
    });
    client.on('loggedIn', Core.handleLogin); <---------------------------------------
}

Game.Events = Events;
})();

最佳答案

您的问题有点令人困惑,因为您说要让this成为Core,但是Core是构造函数。它不是您的对象的实例。因此,您可能在某处需要这样的东西:

 var obj = new Core(xxx);


然后,您可以使用以下方法解决事件处理问题:

client.on('loggedIn', obj.handleLogin.bind(obj));


那是因为当您这样做时:

client.on('loggedIn', obj.handleLogin);


您将获得对handleLogin函数的引用,并将其作为事件处理程序传递。当发生loggingIn事件并调用handleLogin时,将在没有任何对象引用的情况下调用该事件。当一个函数被调用时,即使没有定义为方法的任何函数,也没有任何对象引用,然后this设置为全局对象或未定义(在严格模式下)。这就是您的情况。

这与以下情况相同:

var f = obj.handleLogin;
f();


当您这样做时,handleLogin最终将在没有对象引用的情况下被调用,因此this不会设置为obj

因此,要解决此问题,您必须创建其他方法来将函数与正确的对象引用重新连接。实际上有多种方法可以执行此操作,但是只要您不需要支持旧版IE,.bind()是最简单的方法之一。这是另一种方式:

var obj = new Core(xxx);
client.on('loggedIn', function() {
    return obj.handleLogin.apply(Core, arguments);
});

09-11 17:37