Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript 'this' driving me nuts

I frequently use Visualize to figure out scope, function call sites, and all, while I advance my JS learning escalade. Recently I bumped into this:

function foo() {
    console.log( this.a );
}

var a = 2;

function bar() {
    var a = 5;
    foo();
};

bar();

Google Chrome gives me a 2 in the console, while I was expecting a 5 (foo's call site). Interesting enough, pythongtutor (under JS, of course) gives me an error message of undefined, as seen below:

pytontutor after executing code

I have two questions:

  1. Why the outcome is 2 and not 5 since, calling site for foo is within bar where a is 5.
  2. Why is pythontutor flagging and error?
like image 464
Fernando Soares Avatar asked May 22 '26 05:05

Fernando Soares


1 Answers

1) Why the outcome is 2 and not 5 since, calling site for foo is within bar where a is 5.

The site of a call has no effect whatsoever on this in JavaScript. How you call the function and how that function is defined (e.g., is it a bound function, an arrow function, or just a plain function or method) are all that matters.

2) Why is pythontutor flaggin and error?

Because in strict mode, it would be an error.

When you do:

foo();

...you're not setting any explicit this for the call. If foo is a plain function (and yours is), that means that in loose mode, this will refer to the global object during the call to foo, and see the global object's a property on this.a (and the global a's value is 2). In strict mode, this will be undefined, so this.a is an error (trying to read a from undefined).

Separately, the a local variable in bar isn't accessible as a property of any object.*

Related:

  • How does the “this” keyword work?

* Gory details: Conceptually at a specification level, it's a binding held in the variable environment record (notionally an object) for the execution context of the call to bar (also notionally an object), but that's conceptual. We can't access environment record objects or execution context objects from code, and in a given implementation, they may not literally exist.

like image 61
T.J. Crowder Avatar answered May 23 '26 19:05

T.J. Crowder