javascriptnode.jsecmascript-6evalmjs

Fail to create variable using eval in Node.js ES6


It seems not possible to create a variable using eval in Node.js ES6 but I can't understand why. This happens to me on CentOS 7, but I don't believe OS is the problem here.

Regular Node.js file (test.js):

eval("var a=1");
console.log(a);

Make the same file with .mjs extension to run with Node.js ES6 (test.mjs):

eval("var a=1");
console.log(a);

After that, run the 2 files with Node.js, and Node.js ES6:

$ node test.js
1

$ node --experimental-modules test.mjs
(node:9966) ExperimentalWarning: The ESM module loader is experimental.
ReferenceError: a is not defined
    at file:///temp/test.mjs:2:13
    at ModuleJob.run (internal/modules/esm/module_job.js:96:12)

Is it an issue related to ES6? I tried on browser's console and the problem is the same:

>> eval("var a=1"); console.log(a);
   1

>> class c { static f(){ eval("var a=1"); console.log(a); } }
   c.f()
   ReferenceError: a is not defined

I'm using Node.js 10.9.0, is it a bug or there's a reason behind it?


Solution

  • In strict mode, variables created inside an eval() statement are available only to that code. It does not create new variables in your local scope (here's a good article on the topic) whereas it can create variables in the local scope when not in strict mode.

    And, mjs modules run in strict mode by default. A regular node.js script file is not in strict mode by default. So, the difference in strict mode setting causes a difference in behavior of eval().