Why is an anonymous function required to preserve "this" using setTimeout

javascript, settimeout

Solution

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`).

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

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

Problem

I've used `setTimeout` plenty of times passing a function as a reference e.g. ``` setTimeout(someFunction, 3000); ``` 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" }; ```

Original source

Related problems