Note that there are some explanatory texts on larger screens.

plurals
  1. POIndirect eval call in strict mode
    primarykey
    data
    text
    <p>I understand about how <code>eval()</code> works in non-strict contexts, however the case of using <code>eval()</code> in strict mode has completely befuddled me. When <code>eval()</code> is called directly in the global scope, variables are kept inside the new <code>eval()</code> scope:</p> <pre><code>'use strict'; eval('var a = 1;'); console.log(a); // ReferenceError: a is not defined </code></pre> <p>However, if I perform an <em>indirect</em> call to <code>eval()</code> in the global scope (should be the same thing, right?), it acts as though it is not in strict mode (if you don't believe me, see <a href="http://jsfiddle.net/hSLJq/3/" rel="nofollow noreferrer">this JSFiddle</a>):</p> <pre><code>'use strict'; (0, eval)('var a = 1;'); // indirect call to eval console.log(a); // 1??? </code></pre> <p><sub><em>If you don't understand what <code>(0, eval)</code> does, see <a href="https://stackoverflow.com/questions/19535601/why-does-google-main-page-use-0-obj-funcargs-syntax">Why does google main page use (0, obj.func)(args) syntax?</a>.</em></sub></p> <p>At least according to my understanding of how <code>eval()</code> is supposed to work in strict mode, it is meant to (no matter whether <code>eval()</code> is called directly or indirectly) create a new scope for variables defined in the <code>eval()</code> call, however this doesn't seem to be the case here. The specification says the following:</p> <blockquote> <h3><a href="http://ecma-international.org/ecma-262/5.1/#sec-10.4.2" rel="nofollow noreferrer" title="link to this section">10.4.2</a> Entering Eval Code</h3> <p>The following steps are performed when control enters the execution context for eval code:</p> <ol> <li><p>If there is no calling context or if the eval code is not being evaluated by a direct call (<a href="http://ecma-international.org/ecma-262/5.1/#sec-15.1.2.1.1" rel="nofollow noreferrer">15.1.2.1.1</a>) to the eval function then,</p> <p>a. Initialise the execution context as if it was a global execution context using the eval code as <em>C</em> as described in <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.4.1.1" rel="nofollow noreferrer">10.4.1.1</a>.</p></li> <li><p>Else, </p> <p>a. Set the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">ThisBinding</a> to the same value as the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">ThisBinding</a> of the calling execution context.<br> b. Set the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">LexicalEnvironment</a> to the same value as the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">LexicalEnvironment</a> of the calling execution context.<br> c. Set the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">VariableEnvironment</a> to the same value as the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">VariableEnvironment</a> of the calling execution context.</p></li> <li><p>If the eval code is <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.1.1" rel="nofollow noreferrer">strict code</a>, then</p> <p>a. Let <em>strictVarEnv</em> be the result of calling <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.2.2.2" rel="nofollow noreferrer">NewDeclarativeEnvironment</a> passing the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">LexicalEnvironment</a> as the argument.<br> b. Set the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">LexicalEnvironment</a> to <em>strictVarEnv</em>.<br> c. Set the <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.3" rel="nofollow noreferrer">VariableEnvironment</a> to <em>strictVarEnv</em>.</p></li> <li><p>Perform <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.5" rel="nofollow noreferrer">Declaration Binding Instantiation</a> as described in <a href="http://ecma-international.org/ecma-262/5.1/#sec-10.5" rel="nofollow noreferrer">10.5</a> using the eval code.</p></li> </ol> </blockquote> <p>This is the case in all major browsers, including (but not limited to) Internet Explorer 10, Chrome 30 and Firefox 24 - as all of them have the same behaviour, I don't think it's likely that it's a bug. Aren't they both meant to do the same thing, and if not, why is this the case?</p> <p><sub>Note: <em>please</em> don't tell me to not use <code>eval()</code> (yes, I know the "dangers" of using <code>eval()</code>) - I simply want to understand the logic behind this, which is utterly confusing to me.</sub></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload