Как строгий режим (use strict;) наследуется функциями?

Вот мой код, который, кажется, указывает, что ответ да - http://jsfiddle.net/4nKqu/

var Foo = function() {
    'use strict'
    return {
        foo: function() {
            a = 10
            alert('a = ' + a)
        }
    }
}()

try {
    Foo.foo()
} catch (e) {
    alert(e)
}

Не могли бы вы привести утверждения из стандарта, поясняющие, что 'use strict' автоматически применяется ко всем замыканиям и функциям, определенным внутри функции, к которой мы применили 'use strict'?


person Lone Learner    schedule 02.10.2013    source источник
comment
В любом случае вы можете захотеть явно объявить строгий режим в каждой функции, иначе он оставляет место для ошибки при рефакторинге кода.   -  person Ingo Bürk    schedule 03.11.2013


Ответы (2)


Соответствующая часть спецификации:

http://www.ecma-international.org/ecma-262/5.1/#sec-10.1.1

в котором говорится:

Code is interpreted as strict mode code in the following situations:
  • Глобальный код является строгим глобальным кодом, если он начинается с директивы Prologue, которая содержит директиву Use Strict (см. 14.1).

  • Код Eval является строгим кодом eval, если он начинается с Пролога директивы, который содержит директиву Use Strict, или если вызов eval является прямым вызовом (см. 15.1.2.1.1) функции eval, которая содержится в коде строгого режима.

  • Код функции, который является частью FunctionDeclaration, FunctionExpression или PropertyAssignment средства доступа, является строгим кодом функции, если его FunctionDeclaration, FunctionExpression или PropertyAssignment содержится в коде строгого режима или если код функции начинается с Пролога директивы, который содержит директиву Use Strict.

  • Код функции, передаваемый в качестве последнего аргумента встроенному конструктору Function, является строгим кодом функции, если последним аргументом является строка, которая при обработке как FunctionBody начинается с директивы Prologue, содержащей директиву Use Strict.

Таким образом, для функций, определенных явно в «строгой области», они будут наследовать строгий режим:

function doSomethingStrict(){
    "use strict";

    // in strict mode

    function innerStrict() {
        // also in strict mode
    }
}

Но функции, созданные с помощью конструктора Function, не наследуют строгий режим из своего контекста, поэтому должны иметь явный оператор "use strict";, если вы хотите, чтобы они были в строгом режиме. Например, отметив, что eval является зарезервированным ключевым словом в строгом режиме (но не вне строгого режима):

"use strict";

var doSomething = new Function("var eval = 'hello'; console.log(eval);");

doSomething(); // this is ok since doSomething doesn't inherit strict mode
person Ben Jackson    schedule 02.10.2013

Ответ положительный, но вы, вероятно, не найдете точное предложение в документации, вместо этого там говорится о контекстах. Когда вы определяете функцию Foo внутри другой функции Bar, Foo создается в контексте Bar. Если контекст Bar находится в строгом режиме, это означает, что контекст Foo находится в строгом режиме.

Вы можете посмотреть документацию здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode

Если подумать, отсутствие такого поведения было бы действительно непрактичным (и в этом нет реального недостатка).

Это также полезно, чтобы вся ваша библиотека без проблем использовала строгий режим в случае объединения нескольких скриптов:

Вы также можете использовать подход, заключающий все содержимое скрипта в функцию и заставляющий эту внешнюю функцию использовать строгий режим.

person Lepidosteus    schedule 02.10.2013