vgaltes
vgaltes

Reputation: 1218

Lexical this in JavaScript

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

Answers (1)

Andrew Kovalenko
Andrew Kovalenko

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

Related Questions