为什么需要匿名函数来保存“this"?使用 setTimeout [英] Why is an anonymous function required to preserve "this" using setTimeout
问题描述
我多次使用 setTimeout
将函数作为引用传递,例如
I've used setTimeout
plenty of times passing a function as a reference e.g.
setTimeout(someFunction, 3000);
在某些情况下,为了保留 this
的值,我必须事先将它分配给一个变量,但不明白为什么以下方法不起作用:
In some cases, to preserve the value of this
I've had to assign it to a variable before hand, but don't understand why the following does not work:
var logger = {
log: function() {
var that = this;
console.log(that.msg);
setTimeout(that.log, 3000);
},
msg: "test"
};
logger.log();
然而,使用匿名函数确实有效:
Using an anonymous function however, does work:
var logger = {
log: function() {
var that = this;
console.log(that.msg);
setTimeout(function() { that.log() }, 3000);
},
msg: "test"
};
推荐答案
这不起作用,因为 setTimeout
调用以 this
值作为全局对象的函数,不是父对象.您正在将一个值传递给 setTimeout
函数——它不知道它是如何被访问的,因此无法使用正确的 this
值调用它(与普通变量不同,this
的值仅在调用函数时确定,除非 this
已使用 Function.prototype.bind
绑定到特定值).
This doesn't work as setTimeout
calls a function with the this
value as the global object, not the parent object. You're passing a value into the setTimeout
function -- it doesn't know how it's been accessed, and therefore cannot call it with the correct this
value (unlike normal variables, the value of this
is only determined when you call the function, unless this
has been bound to a specific value using Function.prototype.bind
).
通过将其更改为匿名函数,您将使用闭包来访问 that
的值,即使作为值调用时也是如此(函数的变量范围在定义时设置,而不是在运行时).
By changing that to an anonymous function, you're using the closure to access the value of that
, even when called as a value (the variable scope of a function is set when it is defined, not when it is run).
就像你做这样的事情一样:
It's just like if you do something like this:
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
一起使用的相关问题:将正确的this"上下文传递给 setTimeout 回调?
There's also a related question on using this
with setTimeout
: Pass correct "this" context to setTimeout callback?
这篇关于为什么需要匿名函数来保存“this"?使用 setTimeout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!