为什么需要匿名函数来使用setTimeout保留"this"

Ben*_*ter 8 javascript settimeout

我已经setTimeout多次使用函数作为参考,例如

setTimeout(someFunction, 3000);
Run Code Online (Sandbox Code Playgroud)

在某些情况下,为了保留值,this我必须事先将它分配给变量,但不明白为什么以下不起作用:

var logger = {
    log: function() { 
        var that = this;
        console.log(that.msg); 
        setTimeout(that.log, 3000); 
    },
    msg: "test"
};

logger.log();
Run Code Online (Sandbox Code Playgroud)

但是,使用匿名函数可以正常工作:

var logger = {
    log: function() { 
        var that = this;
        console.log(that.msg); 
        setTimeout(function() { that.log() }, 3000); 
    },
    msg: "test"
};
Run Code Online (Sandbox Code Playgroud)

Qan*_*avy 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
Run Code Online (Sandbox Code Playgroud)

还有使用一个相关的问题thissetTimeout:传递正确的"这个"背景下的setTimeout回调?