Бобинс в основном правильно. (Я работаю над SpiderMonkey, движком Mozilla JS, внедрил в него различные части ES5 и следую за обсуждениями ECMAScript, если позволяет время.) Вы (и разработчики, и читатели оба) действительно хотите, чтобы eval
был каноническим eval
, и Вы хотите, чтобы arguments
был каноническим arguments
. Используя строгий режим, вы можете получить это.
Но я укажу, что ограничения ES5 здесь не такие, как хотелось бы. Во-первых, и немного исправить бобинц, даже в строгом режиме, вы не можете быть уверены, eval
- это оригинальная eval
функция:
"use strict";
this.eval = function() { return "ohai"; };
eval("7 + 10"); // "ohai"
Это общеизвестная (среди поклонников JS) ошибка глобального объекта: сценарии используют глобальный объект, разделяемый между сценариями, именуемые и изменяемые, для разрешения имен. Если бы вы не могли ссылаться на объект, с которым связаны глобальные переменные, у вас не было бы этой проблемы. Вполне вероятно, что ES6 исправит это с помощью другой дополнительной системы (возможно, внеполосной, например, типа MIME, но пока неясно), которая всегда распространяется на все сценарии.
Но даже без именованного, изменяемого глобального объекта у вас все еще есть проблемы, потому что строгий режим может быть ограничен функциями:
function outer()
{
var eval = function() { return "kthxbai"; };
function inner()
{
"use strict";
return eval("2 + 5");
}
return inner();
}
outer(); // "kthxbai"
Эти проблемы существуют даже при наличии строгого режима, и они не исчезнут до ES6 в ближайшее время, так как это, вероятно, удалит глобальный объект и безусловно обеспечит строгие ограничения режима.
Так что eval
в строгом режиме все еще немного странно в том смысле, что он может относиться к not-eval. Но обрабатывать это не составляет особого труда - во время выполнения реализация может проверять наличие реального eval
, а если это не удается, просто делайте то, что делали бы, если бы синтаксис использовал имя, отличное от eval
. Для этого необходимо, чтобы выражение типа eval(...)
было обработано специально. Но любая хорошая реализация сделала это в любом случае, из-за нестатически наблюдаемого поведения eval
(мутирование локальных переменных и аргументов, введение новых переменных [теперь очищено в строгом режиме - объявления переменных в коде eval строгого режима являются локальными) к eval-коду] и т. д.), так что это не реальное бремя.
Стоит отметить, что все это не относится к arguments
как поддельной специальной форме. Либо у вас есть строгий режим с помощью области действия функции, и в этом случае вы увидите , что функции arguments
, а не arguments
, назначенные во внешней области, или у вас есть глобальная функция область действия, в этом случае arguments
не имеет специального поведения. (Зачем запрещать мутацию arguments
в коде глобального строгого режима? Вероятно, простота, а также заставляет разработчиков повсеместно обращаться с ними как с более особой формой, но я не уверен.)