Javascript 为什么需要匿名函数来保存;这";使用setTimeout

Javascript 为什么需要匿名函数来保存;这";使用setTimeout,javascript,settimeout,Javascript,Settimeout,我已经多次使用setTimeout将函数作为参考传递 setTimeout(someFunction, 3000); 在某些情况下,为了保留this的值,我必须事先将其分配给一个变量,但我不明白为什么以下操作不起作用: var logger = { log: function() { var that = this; console.log(that.msg); setTimeout(that.log, 3000); },

我已经多次使用
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"
};

因为在第一种情况下,您仅引用
that
对象中的函数
log
,但它与
that
的关系丢失。可以将其视为
setTimeout
使用全局上下文直接调用存储内存地址处的
log
方法

然而,在第二个示例中,您来自一个全局上下文,但首先查找
,然后使用
上下文调用
日志

设想setTimeout具有以下结构:

var setTimeout = function (func, time) {
   someWaitMechanism(time, function () { //this is called after the timeout
       func.call(null); //calls func with global scope
   });
}

这不起作用,因为
setTimeout
调用的函数将
This
值作为全局对象,而不是父对象。您正在将一个值传递到
setTimeout
函数中——它不知道如何访问它,因此无法使用正确的
值调用它(与正常变量不同,
的值仅在调用函数时确定,除非已使用
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
一起使用:

:setTimeout()执行的代码在调用该函数的函数的单独执行上下文中运行。因此,被调用函数的this关键字将设置为窗口(或全局)对象;它将与调用setTimeout的函数的this值不同。不确定它是否是一个精确的重复,但似乎类似:
func.call(null)
func()
没有什么不同,对吗?您可能想弄清楚;)只是想强调一下
thisArg
被设置为
null
,因此是全局上下文,但你是对的:)事实上,这可能不是那么明显:)