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.