2012-12-26 121 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