2012-12-26 325 views
2

我看到傳遞對象方法作爲setTimeout參數的問題。 我知道里面的嵌套函數,這需要手動設置的範圍,但如果我直接傳遞函數對象,在我的情況this.counting。什麼是需要聲明匿名函數作爲第一個參數,this.counting已經是一個函數。不起作用?

Mozilla也使用函數(msg){self.remind(msg);}而不是this.remind在setTimeout的第一個參數中。

function Timer(count,start){ 
    this.count = count; 
    this.start = start; 

} 

//below code works 
Timer.prototype.counting = function(){ 
    var self = this; 
    setTimeout(function(){self.counting();},this.start); 
    console.log(this.count); 
    this.count++; 
}; 

//below code doesn't work 
/* 
Timer.prototype.counting = function(){ 
    setTimeout(this.counting,this.start); 
    console.log(this.count); 
    this.count++; 
}; 
*/ 
var t1 = new Timer(0,1000); 
t1.counting(); 
var t2 = new Timer(100,1000); 
t2.counting(); 

回答

4

The MDN documentation of setTimeout has a whole section about it,我推薦閱讀它。


傳遞給setTimeout的回調中,this將把window,而不是你的類的實例。

如果函數被調用,this.count(它是指window.count)將是undefined,因爲沒有全局變量count。後來它會變成NaNundefined++NaN)。你的對象的count屬性根本不會改變。

通過顯式調用該函數作爲對象的方法(self.counting()),確保this正確地引用您的類的實例。

您可以通過使用.bind[MDN],而不是使用另一個函數實現相同的:

setTimeout(this.counting.bind(this), this.start); 

this MDN article更多地瞭解this