Reputation: 393
I am trying to understand how Javascript works under the hood so I've been playing around a bit. For example, the following code generates different outputs when in Chrome's console or when in Node.js:
var length = 10;
function fn () {
console.log (this.length);
}
fn();
In Chrome, I get the value 10 logged, while in Node, this is undefined. Is it because in the window object, global variables are treated as properties of window, while in Node, the global object has a different behavior? If so, what is happening in the global object, and how could I get a similar behavior to window, without declaring global.length? I am doing this just as an exercise, there is no other purpose than understanding.
Upvotes: 4
Views: 2946
Reputation: 1074208
The reason for the difference is that the top-level scope in a browser script is the global scope, but the top-level scope in a Node.js file is module scope. (By default it's an old-style Node.js module which is in loose mode, but in modern versions of Node.js you can opt into JavaScript standard module scope, which is in strict mode.)
At global scope, var
creates a property on the global object, which you can access via the window
global, via this
at global scope, or via this
in a loose-mode function you call without doing anything specific to set this
. Your call to fn
above is that last category: a loose-mode function called without setting this
.
But at Node.js module scope, var
just creates a var
in the module, it doesn't create a global or a property on the global object. It's like doing this:
(function() { // The wrapper Node.js provides node-style modules
// This is "module" scope
var foo = 10;
function fn () {
console.log (this.foo);
}
fn();
})(); // End of the wrapper
(Why did I change length
to foo
? Because by default, window
has a length
property [the number of frames the window contains], which confused matters. :-) )
So it's just a difference in scope.
You can also use module scope on modern browsers, including Chrome, via type="module"
on the script
tag. But since JavaScript standard modules are always in strict mode, the this
inside the call to fn
would be undefined
, causing an error:
<script type="module">
var length = 10;
function fn () {
console.log(this); // undefined
console.log(this.length); // TypeError
}
fn();
</script>
Upvotes: 8