Я понимаю, как eval()
работает в нестрогих контекстах, однако случай использования eval()
в строгом режиме полностью меня пугал. Когда eval()
вызывается непосредственно в глобальной области видимости, переменные хранятся внутри новой области eval()
:
'use strict';
eval('var a = 1;');
console.log(a); // ReferenceError: a is not defined
Однако, если я выполняю косвенный вызов eval()
в глобальной области (должно быть одно и то же, верно?), он действует так, как будто это не в строгом режиме (если вы мне не верите, см. этот JSFiddle):
'use strict';
(0, eval)('var a = 1;'); // indirect call to eval
console.log(a); // 1???
Если вы не понимаете, что делает (0, eval)
, см. Почему используется главная страница google (0, obj.func) (args)?.суб >
По крайней мере, согласно моему пониманию того, как eval()
предполагается работать в строгом режиме, он подразумевает (независимо от того, вызывается ли eval()
прямо или косвенно) создать новую область для переменных, определенных в eval()
call, однако, похоже, это не так. В спецификации указано следующее:
10.4.2 Ввод Eval Code
Следующие шаги выполняются, когда элемент управления вводит контекст выполнения для кода eval:
Если контекст вызова отсутствует или код eval не оценивается прямым вызовом (15.1.2.1.1) к функции eval, тогда
а. Инициализировать контекст выполнения, как если бы он был глобальным контекстом выполнения, используя код eval как C, как описано в 10.4.1.1.
/li >Else,
а. Установите ThisBinding с тем же значением, что и ThisBinding контекста вызова вызова.
б. Установите LexicalEnvironment с тем же значением, что и LexicalEnvironment контекста вызова вызова.
с. Установите VariableEnvironment с тем же значением, что и VariableEnvironment контекста вызова вызова.Если код eval строгий код, то
а. Пусть strictVarEnv является результатом вызова NewDeclarativeEnvironment, передающего LexicalEnvironment как аргумент.
б. Установите LexicalEnvironment на strictVarEnv.
с. Установите VariableEnvironment в strictVarEnv.Выполните Активация связывания с объявлением, как описано в 10.5, используя код eval.
Это относится ко всем основным браузерам, включая (но не ограничиваясь ими) Internet Explorer 10, Chrome 30 и Firefox 24 - так как все они имеют одинаковое поведение, я не думаю, что это ошибка. Разве они оба не намерены делать то же самое, а если нет, то почему это так?
Примечание: пожалуйста, не говорите мне, чтобы я не использовал eval()
(да, я знаю "опасности" использования eval()
). Я просто хочу понять логику этого, что совершенно запутывает мне.