Node: Assignment to `undefined` and `Infinity`

Created on 23 Apr 2020  ยท  3Comments  ยท  Source: nodejs/node

  • Version: v12.16.0
  • Platform: Darwin Kernel Version 19.0.0: Wed Sep 25 20:18:50 PDT 2019; root:xnu-6153.11.26~2/RELEASE_X86_64 x86_64
  • Subsystem: Modules?

What steps will reproduce the bug?

So I created the following script as I was experimenting with strict-mode and found a very weird behaviour. If you execute the following code in a script, it logs 19 twice. In the REPL we get the expected error - Uncaught SyntaxError: Identifier 'undefined' has already been declared, same for Infinity as well.
I'm not sure if this is an expected behaviour for a script or a bug

'use strict'

const undefined = 19
const Infinity = 19

console.log(undefined)
console.log(Infinity)

just save this to a file and run the code to observe the behaviour described above.

What is the expected behavior?

Maybe throw the same error that we see in the REPL?

question

Most helpful comment

CommonJS is actually a function wrapper!

globalThis.undefined is non-writable non-configurable property, so assigning to it or trying to shadow it at the top level doesn't work, but functions introduce a new scope.

$ eshost -ts -e "(function() { 'use strict'; const undefined = 42; print(undefined) })()"
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ engine262      โ”‚ 42                                         โ”‚
โ”‚ GraalJS        โ”‚ undefined                                  โ”‚
โ”‚ JavaScriptCore โ”‚                                            โ”‚
โ”‚ SpiderMonkey   โ”‚                                            โ”‚
โ”‚ V8             โ”‚                                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Moddable XS    โ”‚ undefined                                  โ”‚
โ”‚                โ”‚ undefined                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ QuickJS        โ”‚                                            โ”‚
โ”‚                โ”‚ SyntaxError: invalid lexical variable name โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

You can also do this without a function, just introduce a new lexical scope: { const undefined = 42; print(undefined); }

All 3 comments

I tested this on d8, jsc and spidermonkey, all threw an error when trying to assign to undefined or Infinity. But this doesn't seem to be a spec violation (at least I couldn't find anything on https://www.ecma-international.org/ecma-262/10.0/ that prevents users from assigning to those identifiers). With that being said, I think it makes sense for us to prevent assigning to those identifiers as well as other common ones, but that will be a breaking change.

CommonJS is actually a function wrapper!

globalThis.undefined is non-writable non-configurable property, so assigning to it or trying to shadow it at the top level doesn't work, but functions introduce a new scope.

$ eshost -ts -e "(function() { 'use strict'; const undefined = 42; print(undefined) })()"
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ engine262      โ”‚ 42                                         โ”‚
โ”‚ GraalJS        โ”‚ undefined                                  โ”‚
โ”‚ JavaScriptCore โ”‚                                            โ”‚
โ”‚ SpiderMonkey   โ”‚                                            โ”‚
โ”‚ V8             โ”‚                                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Moddable XS    โ”‚ undefined                                  โ”‚
โ”‚                โ”‚ undefined                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ QuickJS        โ”‚                                            โ”‚
โ”‚                โ”‚ SyntaxError: invalid lexical variable name โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

You can also do this without a function, just introduce a new lexical scope: { const undefined = 42; print(undefined); }

I'm closing this as answered.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jonathanong picture jonathanong  ยท  93Comments

egoroof picture egoroof  ยท  90Comments

silverwind picture silverwind  ยท  113Comments

jonathanong picture jonathanong  ยท  91Comments

VanCoding picture VanCoding  ยท  204Comments