我多次使用setTimeout
传递一个函数作为参考,例如
setTimeout(someFunction, 3000);
在某些情况下,要保留this
的值,我必须事先将其分配给变量,但不明白为什么以下内容不起作用:
var logger = {
log: function() {
var that = this;
console.log(that.msg);
setTimeout(that.log, 3000);
},
msg: "test"
};
logger.log();
然而,使用匿名函数确实有效:
var logger = {
log: function() {
var that = this;
console.log(that.msg);
setTimeout(function() { that.log() }, 3000);
},
msg: "test"
};
答案 0 :(得分:5)
这不起作用setTimeout
调用一个this
值作为全局对象而不是父对象的函数。您已将值传递到setTimeout
函数 - 它不知道它是如何被访问的,因此无法使用正确的this
值调用它(不像正常变量,this
的值仅在您调用函数时确定,除非使用this
将Function.prototype.bind
绑定到特定值。
通过将其更改为匿名函数,您可以使用闭包来访问that
的值,即使在作为值调用时(函数的变量范围在定义时设置,不是什么时候运行。)
就像你做这样的事情一样:
var a = { b: function () { return this.foo; }, foo: 'proper' };
function test(arg) {
return arg();
}
var foo = 'random';
console.log(a.b()); // proper
console.log(test(a.b)); // random
还有一个与this
setTimeout
{{1}}一起使用的相关问题:Pass correct "this" context to setTimeout callback?
答案 1 :(得分:2)
因为在第一种情况下,您只引用log
对象中的函数that
,但它与that
的关系丢失了。可以认为它是setTimeout
直接使用全局上下文在存储的内存地址调用log
方法。
在第二个示例中,您来自全局上下文,但是先查找that
,然后查找log
,然后调用that
的上下文。
认为setTimeout具有以下结构:
var setTimeout = function (func, time) {
someWaitMechanism(time, function () { //this is called after the timeout
func.call(null); //calls func with global scope
});
}