2012-10-15 20 views
1

我有以下Javascript代碼,並且我試圖讓回調工作,如下所示。我想看到裏面有「123」的警報。Javascript回調和「這個」

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 

我明白髮生了什麼,但我不知道如何解決它。我怎樣才能得到一個引用我的對象的回調函數?就我而言,我可以進行更改,但不B.

+0

您是否嘗試過剛剛警報(ARG)? –

+0

@Jack,我不認爲最終目標是顯示警報。 – andytuba

回答

2

所以,你想要的是上下文傳遞給doCallBack

E.g.

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

,那麼你會怎麼做:

b.doCallBack(a.callback, a); 

如果您不能修改B,則可以用瓶蓋內答:

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

這需要修改B類,對吧?不幸的是,我不能這樣做。 – Watusimoto

+0

@Watusimoto我添加了第二個版本,當你無法修改B –

2

您可以創建包含想要一個變量餘地this是放入變量that

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

工作演示在這裏:http://jsfiddle.net/vdM5t/

1

我明白髮生了什麼(第二個回調過程中,「本」爲b,而不是一個)

沒有,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 
    }; 
} 
+0

是的,你是對的;我做了一些記錄,顯示了這個== b,但我的聲明並沒有說清楚我在哪裏觀察到這一點。 – Watusimoto

0

當你這樣做:

b.doCallback(a.callback); 

,只是調用的callback功能而不告訴它使用athis;所以全局對象用於this

一種解決方法是換行回調了起來:

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

其他解決方案包括binding回調a,使用jQuery.proxy()(這是在做我的第一個解決方案只是一個有趣的方式),或傳遞adoCallback並使用applya上調用callback

1

您需要將您想要的回調執行上下文:

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

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

http://jsfiddle.net/a9N66/

1

因爲裏面A.callback功能,this並不是指Awindow對象。

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 
+0

這個''不是指'A.callback'(它不存在),也不應該指'A'。 – Bergi