3

In the browser and the NodeJS REPL the following prints true, but running as a file (ie. node filename.js) under NodeJS it prints false. Why?

All in non-strict mode, in the global context.

var x = 1
console.log(window.hasOwnProperty('x')) // replace `window` with `global` for NodeJS

I am sure I am missing something obvious.

Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • 4
    Node has module scope for what would be global (`window`) variables in a browser context. – Pointy Apr 10 '20 at 13:55
  • I will accept that as the answer. – Ben Aston Apr 10 '20 at 13:56
  • 1
    @52d6c6af Here is a [link](https://nodejs.org/api/globals.html#globals_global) to the docs, explaining this clearly. – Fullstack Guy Apr 10 '20 at 14:03
  • That documentation is surely wrong. The top-level scope in Node _is_ the global scope - otherwise intrinsics would be out of scope in modules. It's just that variable declarations in modules occur within the scope of the module. – Ben Aston Apr 10 '20 at 14:26
  • @52d6c6af It means "*The top-level scope [of module code] is not the global scope*", with "top-level" referring to the evaluated code, not the scope hierarchy of the whole program. – Bergi Apr 10 '20 at 14:32
  • The top-level scope of module code is the global scope though. All the intrinsics and host objects are in scope as a result. Also, variable declarations at the top of modules are scoped to that module. – Ben Aston Apr 10 '20 at 14:43

1 Answers1

3

They behave differently because Node.js wraps each module in a function, so variables are not scoped to the global object (window, global etc.):

The module wrapper

Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following:

(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});

By doing this, Node.js achieves a few things:

  • It keeps top-level variables (defined with var, const or let) scoped to the module rather than the global object.
  • It helps to provide some global-looking variables that are actually specific to the module, such as:

    • The module and exports objects that the implementor can use to export values from the module.
    • The convenience variables __filename and __dirname, containing the module's absolute filename and directory path.
Frxstrem
  • 38,761
  • 9
  • 79
  • 119