Reputation: 66
I'm reading the "You don't know JS" book series and I tried to run the snippet:
function foo() {
console.log( this.a );
}
function doFoo(fn) {
// `fn` is just another reference to `foo`
fn(); // <-- call-site!
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global"; // `a` also property on global object
doFoo( obj.foo ); // "oops, global"
(You can find it in the 2nd chapter of the 3d book: 'this' All make sense now)
If I save this into 'foo.js' and run it with node foo.js (v 8.11.1) then I get undefined
. While if I start node REPL and type in the same code I get:
> function foo() { console.log(this.a); }
undefined
> function doFoo(fn) { fn(); }
undefined
> var obj = { a:2, foo:foo };
undefined
> var a = "oops, global";
undefined
> doFoo(obj.foo);
oops, global
undefined
As expected from the book. Same result on Firefox dev console.
If I remove the declaration and leave only the assignment a = "oops, global"
then it run as expected both on REPL and Node.js. This make more sense to me because in this way I'm setting a property on the global object, while in the "original" way I'm just declaring a variable.
Can anyone explain to me this behaviour? Thank you all.
EDIT: I think I'm close to the solution, I noticed that if I make a script foo.js that contains only:
var x = 42;
console.log(this);
I get {}
, so x
is not attached to the global object. While if I start the Node.js REPL and type in the same code I get a big object with x
attached to it:
{
...
x: 42
}
So I think the difference it depends on "who is the global object?" in REPL and in Node.js.
Upvotes: 1
Views: 468
Reputation: 34667
When you run the file in Node.js, your var a
isn't actually in global scope, but function scope -- a module function scope (more on this here). Basically all of the contents of the file is run as if inside a function. So var a
is actually in that function scope.
Whereas in REPL it's truly in global scope.
Upvotes: 1