3

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?
Ghassen Louhaichi
  • 3,961
  • 1
  • 20
  • 32

1 Answers1

5

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:


* 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.

T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • 1
    "is a plain function" --- what does "plain" here mean? – zerkms Oct 28 '17 at 11:13
  • @zerkms: I thought I'd made that clear by contrast: Not bound or arrow. – T.J. Crowder Oct 28 '17 at 11:14
  • Right, that's what I thought as well. It's unfortunate there is no a dedicated name for it :-( – zerkms Oct 28 '17 at 11:14
  • 1
    @zerkms: Yeah. I reworded slightly to make that bit clearer. I've heard "plain", "normal", and I've uncreatively used "`function` function" (but that doesn't really make sense, as methods aren't declared with `function` but are "plain" in this regard...sigh!). – T.J. Crowder Oct 28 '17 at 11:17