Javascript回调和“这个”

时间:2012-10-15 14:48:29

标签: javascript callback

我有以下Javascript代码,我正在尝试让回调工作,如下所示。我希望看到一个带有“123”的警报。

var A = function(arg){
    this.storedArg = arg;
    this.callback = function(){ alert(this.storedArg); }
}

var B = function() {
    this.doCallback = function(callback){ callback(); }
}       

var pubCallback = function(){ alert('Public callback') };

var a = new A(123);
var b = new B();

b.doCallback(pubCallback); // works as expected
b.doCallback(a.callback);  // want 123, get undefined

我明白发生了什么,但我不确定如何解决它。如何获得引用我的对象的回调函数?在我的情况下,我可以更改A而不是B。

6 个答案:

答案 0 :(得分:2)

所以你想要的是将上下文传递给doCallBack

E.g。

doCallBack = function (callback, callee) { 
    callback.apply(callee);
}

那么你会这样做:

b.doCallBack(a.callback, a);

如果你不能修改B,那么你可以在A:

中使用闭包
var A = function (arg) {
    var self = this;
    this.storedArg = arg;
    this.callback = function () { alert(self.storedArg); }
}

答案 1 :(得分:2)

您可以通过将this变为that来创建一个包含var A = function(arg){ this.storedArg = arg; var that = this; // Add this! this.callback = function(){ alert(that.storedArg); } } 所需范围的变量

{{1}}

此处的演示演示:http://jsfiddle.net/vdM5t/

答案 2 :(得分:1)

  

我明白发生了什么(在第二次回调中,“这个”是b而不是a)

不,JS不是基于类的语言,可能会发生某些事情。如果function(){ alert(this.storedArg);仅被称为callback();(如b.doCallback中所述),则this keyword指向全局对象(window)。

要解决这个问题,您必须将A更改为

var A = function(arg){
    var that = this; // store reference to the current A object
    this.storedArg = arg;
    this.callback = function(){
        alert(that.storedArg); // and use that reference now instead of "this"
    };
}

如果您不希望storedArg属性发生变化,您甚至可以更简单:

var A = function(arg){
    this.storedArg = arg;
    this.callback = function(){
        alert(arg); // just use the argument of the A function,
                    // which is still in the variable scope
    };
}

答案 3 :(得分:1)

您需要传递要在其中执行回调的上下文:

var B = function() {
    this.doCallback = function(callback, context) {
        callback.apply(context); 
    };
};

b.doCallback(a.callback, a); // 123

http://jsfiddle.net/a9N66/

答案 4 :(得分:1)

因为在A.callback函数内,this不是A而是window对象。

var A = function(arg){
    this.storedArg = arg;
    this.callback = function(){ alert(this.storedArg); }
    -----------------------------------^-----------------
}

你可以试试这个,

var A = function(arg){
    this.storedArg = arg;
    var that = this;
    this.callback = function(){ alert(that.storedArg); }
}

var B = function() {
    this.doCallback = function(callback){ callback(); }
}       

var pubCallback = function(){ alert('Public callback') };

var a = new A(123);
var b = new B();

b.doCallback(pubCallback); // works as expected
b.doCallback(a.callback);  // alerts 123

答案 5 :(得分:0)

执行此操作时:

b.doCallback(a.callback);

只是调用callback函数而不告诉a使用this;所以全局对象用于this

一种解决方案是将回调包装起来:

b.doCallback(function() { a.callback(); });

其他解决方案包括binding回调a,使用jQuery.proxy()(这只是我第一个解决方案的一种奇特方式),或者将a传递给doCallback {1}}并使用applycallback上调用a