Reputation: 1218
I've just read the book "Scope and Closures" of the series You Don't Know Javascript. The book has an appendix talking about Lexical this. It gives an example of how this can lose its binding and how can be solved using arrow functions.
I'm having problems with the example of the first situation. This is the example of the book:
var obj = { id: 2, cool: function(){console.log(this.id)}}
id=3;
obj.cool();
setTimeout(obj.cool, 100);
This works fine an prints the expected result: 2 the first time, and 3 in the setTimeout call.
But if I change this call by:
var obj = { id: 2, cool: function(){console.log(this.id)}}
id=3;
obj.cool();
setTimeout(function(){obj.cool()}, 100);
It prints 2 both times.
My guess is that, by enclosing the call to obj.cool inside a function, I'm creating a scope where id has the expected value.
Am I right? Is this the right explanation? Am I missing something?
Upvotes: 1
Views: 449
Reputation: 6710
Not exactly. In the first example setTimeout
calls your cool
function not as a method, but as a simple function. That's why you "inherit" a "global" scope and id
is equal to 3.
If you call a function with .
notation, like in a second example - your call scope is whatever you put before .
and since obj.id === 2
- you see 2 printed.
The key to understand this is: setTimeout
gets a reference to just a function. It doesn't know that your function is a method of an object. It doesn't know anything about this object either. All it gets is just a reference to a "code to execute". In the second scenario you explicitly tell to an interpreter that you want to execute function cool
as a method of the object obj
.
Upvotes: 3