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"
};
Anonymous functions, also known as closures , allow the creation of functions which have no specified name. They are most useful as the value of callable parameters, but they have many other uses. Anonymous functions are implemented using the Closure class.
An anonymous function is not accessible after its initial creation, it can only be accessed by a variable it is stored in as a function as a value. 3. This function is useful for all scenarios. An anonymous function can be useful for creating IIFE(Immediately Invoked Function Expression).
An anonymous function is a function that was declared without any named identifier to refer to it. As such, an anonymous function is usually not accessible after its initial creation. Normal function definition: function hello() { alert('Hello world'); } hello();
Summary. Anonymous functions are functions without names. Anonymous functions can be used as an argument to other functions or as an immediately invoked function execution.
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?
Because in the first case you reference only the function log
that is within the that
object, but its relationship to that
is lost. Think of it as setTimeout
calls directly the log
method at the stored memory address with the global context.
In the second example however you come from a global context, but first that
is looked up, and afterwards log
which is called then with the context of that
.
Think of setTimeout having the following structure:
var setTimeout = function (func, time) {
someWaitMechanism(time, function () { //this is called after the timeout
func.call(null); //calls func with global scope
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With