当我定义并调用setTimeout函数时,我得到了undefined undefined,如下所示:
var person = {
first: 'joe',
last: 'doe',
getName: function(){
console.log(this.first + ' ' + this.last);
}
}
setTimeout(person.getName(), 2000);除非我将person.getName()包装在一个函数中,如下所示:
setTimeout(function(){
person.getName()
}, 2000);现在我得到了正确的输出。为什么会这样呢?
发布于 2013-05-30 09:21:15
假设你的意思是:
var person = {
first: 'joe',
last: 'doe',
getName: function(){
console.log(this.first + ' ' + this.last);
}
}
setTimeout(person.getName, 2000);你得不到定义的原因是你正在有效地做的是:
var somefunc = person.getName;
setTimeout(somefunc, 2000);因此,在window的上下文中调用了一些函数。即window.somefunc()
然而,当你这样做的时候
setTimeout(function(){
person.getName()
}, 2000);在调用(而不是传递) person.getName时,会保留getName的上下文
发布于 2013-05-30 15:44:40
我刚刚在这里回答了类似的问题:
How can I pass a parameter to a setTimeout() callback?
setTimeout函数将上下文固定到窗口,因此不可能执行您想要的操作!
为此,我将setTimeout函数包装在另一个可以设置上下文的函数中:
myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
var _deepResultFunction = function _deepResultFunction(){
//_deepFunction(_deepData);
_deepFunction.apply( _deepCtxt , _deepData);
};
return _deepResultFunction;
})(fn , params , ctxt)
, _time)
};
// lets try this functions :
for(var i=0; i<10; i++){
setTimeout(function(){console.log(i)} ,1000 ); // stock setTiemout in closure
}
for(var i=0; i<10; i++){
setTimeout( console.log(i) ,1000 ); // stock setTiemout direct call
}
for(var i=0; i<10; i++){
setTimeout(console.log ,1000 , i); // stock setTiemout not compatible IE
}
for(var i=0; i<10; i++){
myNass_setTimeOut(console.log ,1000 , [i] , console); // wrapped setTimeout
}所以我来回答你的问题:
var person = {
first: 'joe',
last: 'doe',
getName: function(){
console.log(this.first + ' ' + this.last);
}
}
setTimeout(person.getName(), 2000);启动时:setTimeout(person.getName(), 2000); setTimeout将在未来2秒(2000ms)内执行第一个参数!
但是你的第一个参数的值是什么?:你的函数person.getName( )的结果,所以它等同于:
var _arg1 = person.getName();
setTimeout(_arg1 , 2000);这是非常不同的:
var _arg1 = person.getName;
setTimeout(_arg1 , 2000);在第一种情况下,您将函数的结果传递给setTimeout,它等待对函数的引用。在第二种情况下,您传递了对函数的引用(很好,这是预期的),但不是在好的上下文中!
因此,现在您必须修复上下文:核心javascript函数:apply
现在试试这个:
var _arg1 = function(){ person.getName.apply(person) };
setTimeout(_arg1 , 2000);
myNass_setTimeOut(person.getName , 2000 , null , person);所以你有两个选择:
修复传递给setTimeout.
myNass_setTimeOut函数将会成功!
现在,让我们来看一些更深层次的东西:
var person = {
first: 'joe',
last: 'doe',
getName: function(){
console.log(this.first + ' ' + this.last);
} ,
say : function(sentence){
console.log(this.first + ' ' + this.last + ' say : ' + sentence)
}
}如何将参数语句传递给setTimeout?
var heSay = "hello !"; setTimeout(person.say(heSay) , 1000 ); heSay = "goodBye !";
// not good : execute immediatly
var heSay = "hello !";setTimeout(function(){person.say(heSay)} , 1000 ); heSay = "goodBye !";
// not good : hesay googbye
var heSay = "hello !"; setTimeout(person.say , 1000 , heSay); heSay = "goodBye !";
// not good bad context
var heSay = "hello !"; setTimeout(function(whatHeSay){person.say(whatHeSay)} , 1000 , heSay);heSay = "goodBye !";
// GOOD ! ok but not compatible with IE
var heSay = "hello !"; myNass_setTimeOut(person.say , 1000 , [heSay] , person ); heSay = "goodBye !";
// just good !希望这对你有帮助!
编辑:
对于支持bind的现代浏览器来说,不要关心这一点,比如here @dandavis
发布于 2013-05-30 09:08:25
解决方案?
使用bind,不要提前调用它:
var person = {
first: 'joe',
last: 'doe',
getName: function(){
console.log(this.first + ' ' + this.last);
}
}
setTimeout(person.getName.bind(person), 2000);https://stackoverflow.com/questions/16826337
复制相似问题