1

在下面的例子中,作为参数发送给方法“lostThis”对象“instObj”,“this”是窗口对象。

var obj = function() {};
obj.prototype.lostThis = function() {
    console.log('lostThis', this instanceof obj, this);
};

var instObj = new obj;

var caller = {
    runFn: function(fn) {
        fn();
    }
};

caller.runFn(instObj.lostThis);

控制台响应:

lostThis false Window

运行示例

在下面的例子中(稍微复杂一点),有不同的方法来调用“instObj”的方法,它是相同的,而其他的方法我可以保留“this”对象。

var obj = function() {};

obj.prototype.methodRefHasThis = function() {
    var t = this;
    return function() {
        console.log('methodRefHasThis ', t instanceof obj, t);
    };
};

obj.prototype.methodRefLostThis = function() {
    console.log('methodRefLostThis ', this instanceof obj, this);
};

obj.prototype.methodRefMaybeThis = function() {
    console.log('methodRefMaybeThis ', this instanceof obj, this);
};

var instObj = new obj;
var caller = {
    runFn: function(fn) {
        fn();
    }
};

// width jQuery
$('button')
    .bind('click', instObj.methodRefHasThis())
    .bind('click', instObj.methodRefLostThis);

caller.runFn(instObj.methodRefHasThis());
caller.runFn(instObj.methodRefLostThis);
caller.runFn(function() {
    instObj.methodRefMaybeThis();
});​

控制台响应:

methodRefHasThis  true obj
methodRefLostThis  false Window
methodRefMaybeThis  true obj

methodRefHasThis  true obj
methodRefLostThis  false <button>​press here​&lt;/button>​

运行示例

我知道 jQuery 会发生这种情况以将方法分配给事件,但我可以调用方法“methodRefLostThis”而不丢失“this”对象以通过引用传递吗?

谢谢

@am_not_i_am、@Dan_Davies_Brackett 和 @Ben_Lee 的解决方案

var obj = function() {};
obj.prototype.lostThis = function() {
    console.log('lostThis', this instanceof obj, this);
};

var instObj = new obj;

var caller = {
    runFn: function(fn) {
        fn();
    }
};

caller.runFn(instObj.lostThis.bind(instObj));
caller.runFn($.proxy(instObj.lostThis, instObj));

控制台响应:

lostThis true obj
lostThis true obj

 ​

运行示例

4

3 回答 3

2

您可以使用bind将对象绑定到this被调用方。例如:

caller.runFn(instObj.lostThis.bind(this));

在这里,this方法运行时的 at 将被转移到thisin lostThis

于 2012-06-13T19:46:22.197 回答
2

有两种方法可以解决这个问题。this您可以捕获对(我通常称之为)的本地引用self,然后在方法内部使用self.而不是使用this.,或者您可以使用函数绑定。

Ben Lee 给出了 JS5 的绑定方式;jQuery.proxy 是不支持Function.bind.

于 2012-06-13T19:48:20.943 回答
0

如果您不想使用您发现有效的技术之一,您可以使用Function.prototype.bind将调用上下文绑定到新函数...

caller.runFn(instObj.lostThis.bind(instObj));

这将返回一个新函数,当调用该函数时,会将调用上下文设置为您作为第一个参数传递给.bind().

传递给的任何附加参数.bind()都将设置为返回函数的固定参数。

于 2012-06-13T19:46:31.950 回答