Difference between window (browser) and global (Node.js) objects

Cipriana :

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.

T.J. Crowder :

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>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=11702&siteId=1