Convert a JavaScript string into an executable code [duplicate]

When I try to define a variable using var, everything is working.

But defining it as const is not working as expected and the variable is undefined.

window.eval("var v = 5;");
document.body.innerHTML += window.v === undefined;

window.eval("const l = 5;");
document.body.innerHTML += window.l === undefined;

I have tested it on Chrome and Node.js. Am I missing something?

Thank you in advance!


Solution 1:

Using let and const in eval code doesn't invoke strict mode. let and const are lexicalDeclarations, which limits their scope to the enclosing lexical scope.

A lexical scope is created by a block and by direct call to eval (see Runtime Semantics: PerformEva step 12).

Solution 2:

That is because const turns on the strict mode by default. See what happens when you turn on the strict mode for both examples explicitly:

window.eval("'use strict'; var v = 5;");
document.body.innerHTML += window.v === undefined;

window.eval("'use strict'; const l = 5;");
document.body.innerHTML += window.l === undefined;

For more info on the strict mode see:

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

In particular this part:

Second, eval of strict mode code does not introduce new variables into the surrounding scope. In normal code eval("var x;") introduces a variable x into the surrounding function or the global scope. This means that, in general, in a function containing a call to eval every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that eval might have introduced a new variable that would hide the outer variable). In strict mode eval creates variables only for the code being evaluated, so eval can't affect whether a name refers to an outer variable or some local variable [emphasis added]

See also this article:

  • New ES5 strict mode support: new vars created by strict mode eval code are local to that code only