我有以下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。
答案 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
答案 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}}并使用apply在callback
上调用a
。