为什么需要匿名函数来保存“this"?使用 setTimeout [英] Why is an anonymous function required to preserve "this" using setTimeout

查看:50
本文介绍了为什么需要匿名函数来保存“this"?使用 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

还有一个关于将 thissetTimeout 一起使用的相关问题:将正确的this"上下文传递给 setTimeout 回调?

There's also a related question on using this with setTimeout: Pass correct "this" context to setTimeout callback?

这篇关于为什么需要匿名函数来保存“this"?使用 setTimeout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆