Определение eval в качестве формального параметра вызова конструктора функции.Разве это не должно вызвать синтаксическую ошибку в коде строгого режима? - PullRequest
3 голосов
/ 10 декабря 2011

В спецификации указано:

Это ошибка синтаксиса для использования в коде строгого режима идентификаторов eval или аргументы в качестве идентификатора FunctionDeclaration или FunctionExpression или как формальное имя параметра (13.1). Пытаться динамически определять функцию такого строгого режима, используя функцию конструктор (15.3.2) сгенерирует исключение SyntaxError.

Источник: http://es5.github.com/C.html#C (последняя пуля)

Следовательно, возникает синтаксическая ошибка (в Firefox, Chrome и Opera):

(function () {
    'use strict';

    var f = function ( eval ) {};
})();

Демонстрационная версия: http://jsfiddle.net/v8Ff4/

Однако, это не вызывает синтаксическую ошибку:

(function () {
    'use strict';

    var f = new Function( 'eval', '' );
})();

Демонстрационная версия: http://jsfiddle.net/v8Ff4/1/

Насколько я понимаю, этот второй кодовый блок должен выдавать синтаксическую ошибку. Должно ли это? И если да, то почему нет?

1 Ответ

2 голосов
/ 12 декабря 2011

Итак, я собираюсь ответить на свой вопрос здесь (поскольку я понял это).

Моя первоначальная предпосылка заключалась в том, что оба кодовых блока эквивалентны.Так что это

var f = function ( eval ) {};

эквивалентно

var f = new Function( 'eval', '' );

Это, однако, не так.Есть отличия.Создание функционального объекта из объявления функции / нотации выражений определено в Глава 13.2 Создание функциональных объектов .С другой стороны, создание функционального объекта из вызова конструктора new Function определено в Глава 15.3.2.1 new Function (p1, p2,…, pn, body) .Так что здесь работают разные алгоритмы.

Конкретная часть, которая имеет отношение к этому вопросу, - это часть, которая определяет строгость созданного функционального объекта.

Функциональные выражения

Строгость функционального объекта, созданного с помощью функционального выражения, определяется в семантике производства FunctionExpression в началеглава 13:

Передать true как флаг Strict, если выражение FunctionExpression содержится в строгом коде или если его FunctionBody является строгим кодом.

Таким образом, объект функции будетстрогий, если выполняется одно из следующих условий:

  • выражение функции содержится в строгом коде
  • тело функции выражения функции - строгий код

так, например, функция f является строгой в обоих приведенных ниже примерах.

Пример 1:

(function () {    
    var f = function () {
        'use strict';
        return 'I am strict!';
    }    
})();

Пример 2:

(function () {
    'use strict';    
    var f = function () {
        return 'I am strict!';
    }    
})();

Вызов конструктора функции

Строгость функционального объекта, созданного с помощью вызова конструктора функции, определена на шаге 9 алгоритма из главы 15.3.2.1 (уже связанаbove):

Если body - это код режима строгого режима (см. 10.1.1), тогда пусть strict будет true, иначе пустьеверный будет false.

Итак, независимо от того, действительно лиnew Function вызов содержится в строгом коде не имеет значения .Чтобы создать строгую функцию через этот шаблон, необходимо явно определить строгость в теле функции (которое является последним аргументом, предоставленным конструктору.

new Function ( 'a, b', 'return a + b;' ); // not strict
new Function ( 'a, b', '"use strict"; return a + b;' ); // strict
...