В ECMAScript5 какая сфера использования строгая?

Какую область действия имеет прагма строгого режима в ECMAScript5?

"use strict";

Я хотел бы сделать это (в основном потому, что JSLint не жалуется на это):

"use strict";

(function () {
  // my stuff here...
}());

Но я не уверен, что это сломает другой код или нет. Я знаю, что я могу сделать это, что применит прагму к функции...

(function () {

  "use strict";

  // my stuff here...

}());

но JSLint жалуется на это (когда включена опция «строгий» JSLint), потому что он думает, что вы выполняете код, прежде чем включить «использовать строгий».

Вот мой вопрос. Если у меня есть файл A.js:

"use strict";
// do some stuff

и файл B.js:

eval( somecodesnippet ); // disallowed by "use strict"

а затем включить их в мою html-страницу в том же порядке, будет ли прагма привязана к файлу или прагма перейдет в файл B, тем самым заблокировав выполнение eval?


person Stephen Sorensen    schedule 26.02.2010    source источник
comment
Примечание: презентация Дугласа Крокфорда «Состояние и будущее Javascript» была действительно великолепной. В конце выступления он обсуждает некоторые новые функции, такие как строгость. Вот ссылка: infoq.com/presentations/The-State- и-будущее-JavaScript   -  person David Robbins    schedule 27.02.2010
comment
eval() разрешено с "use strict", оно просто становится глобальным.   -  person Eli Grey    schedule 22.03.2010


Ответы (4)


ИЗМЕНИТЬ Похоже, я ошибся. См. ответ Джеффа Уолдена ниже.

Ознакомьтесь с этим ответом на связанный вопрос: Что такое strict do в JavaScript и чем это объясняется?

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

person ntownsend    schedule 27.02.2010
comment
Этот ответ неверен. Использование директивы в начале fileA.js приводит к тому, что весь этот файл находится в строгом режиме, но не приводит к тому, что fileB.js находится в строгом режиме, независимо от порядка их включения в HTML-страницу. Далее, eval() в строгом режиме работает иначе, но все равно работает. Он не заблокирован. - person Darshan Rivka Whittle; 19.06.2012

"use strict" применяется только к функции или области программы. Итак, если у вас есть fileA.js с "use strict" вверху, fileA.js выполняется в строгом режиме, и все функции, определенные в нем, будут делать то же самое при вызове. Но fileB.js — это отдельная программа, поэтому "use strict" из fileA.js к ней не применяется — и, следовательно, fileB.js будет выполняться в нестрогом режиме. (Конечно, если somecodesnippet начинается с директивы "use strict" и анализируется должным образом, этот код будет выполняться в строгом режиме, и функции, определенные этим кодом, будут выполняться аналогичным образом.) Строгость абсолютно не "кровоточит" - и согласно ES5 4.2.2 ( по общему признанию, ненормативный, но я уверен, что мог бы найти нормативную ссылку для этого, если это необходимо), «реализация должна поддерживать комбинацию кодовых единиц неограниченного и строгого режима в одной составной программе».

Один нюанс: если вы используете строгий режим в глобальной области видимости иногда, но не всегда, вы больше не сможете объединять свои скрипты в один файл. Предположим, у вас есть сценарии A, B, C, D в таком порядке. Если A является строгим, общая конкатенация будет строгой, даже если B/C/D нет! И наоборот, если A не является строгим (и непустым), общая конкатенация будет нестрогой, даже если B/C/D были строгими. Это уже нанесло удар по крайней мере одному сайту-первопроходцу.

При этом строгий режим не запрещает eval. Когда eval вызывается обычным способом в строгом режиме, используя программный синтаксис формы eval(code [, ...]), это "прямая" оценка, которая ведет себя так, как всегда eval, за исключением того, что code всегда оценивается как код строгого режима, даже если code не t начинается с директивы "use strict", и за исключением того, что любые переменные, созданные кодом, хранятся в отдельном хранилище от любых существующих переменных. (Точная семантика немного сложна; я работаю над движком JavaScript Firefox, недавно реализовал этот материал, и даже после достаточного количества времени в спецификации и работы над реализацией это все еще не интуитивно понятно для меня.)

Если он не называется таким образом — eval.call(...), setTimeout(eval, ...), setInterval(eval, ...), var ev = eval; ev(...); и т. д. — это «косвенный» eval. Косвенный eval (будь то внутри или вне строгого режима) ведет себя немного иначе: разрешение имен и определение переменных происходят как бы в глобальной области видимости. (Код будет выполняться как код строгого режима, только если он начинается с директивы "use strict".)

Поддержка строгого режима почти, но не полностью, завершена в последних ночных сборках Firefox, так что, возможно, стоит загрузив один, чтобы поиграть с теми частями строгого режима, которые реализованы. Я бы все же посоветовал отложить использование в продакшене до тех пор, пока он не будет завершен, но он определенно готов для экспериментов (если вы понимаете, что строгий режим еще не полностью реализован). (Что касается ссылки Шона Макмиллана, имейте в виду, что его заявления о «поддержке» представляют собой крайний минимум функциональности, необходимой для каждой пули. Тесты в строгом режиме намного лучше, хотя, чтобы быть уверенным, они и близко не охватывают строгий режим полностью. )

person Jeff Walden    schedule 08.10.2010
comment
«Строгость абсолютно не кровоточит» — это не совсем правильно. Вы не можете использовать .caller в нестрогом коде, если функция, в которой вы его используете, была определена в строгом режиме. Таким образом, нестрогий код может фактически сломаться из-за того, что другой код находится в строгом режиме - я бы счел это кровотечением. - person AndreKR; 06.04.2014
comment
То, как был сформулирован первоначальный вопрос, я бы интерпретировал bleed как означающий в лексическом, текстовом смысле исходного кода - сценарий B получает строгость от сценария A, без того, чтобы B сам выбирал строгость. Очевидно, что эффекты сценария (в том числе вызванные строгостью) видны — можно сказать, кровоточащие — в других сценариях. Природа эффекта может различаться в зависимости от строгости запускающего скрипта. Но строгие они или нет, эффекты одного сценария видны и в другом. Мне это не кажется особенно подходящим определением кровотечения. - person Jeff Walden; 09.04.2014

eval( somecodesnippet ); // disallowed by "use strict"

Нет, если вы объявите somecodesnippet раньше.

var somecodesnippet = "Ваш замечательный фрагмент кода здесь";

eval(какой-то фрагмент кода); // НЕ запрещено "use strict"

person MTK    schedule 08.06.2016

Весь файл:

<script...>
  "use strict";

or

Вся функция и ее встроенные функции, например:

function fn(){
  "use strict";
person Jean-Dadet Diasoluka    schedule 12.01.2018
comment
Уже есть принятый ответ, который решает проблему OP. Ваш уже не добавляет качества. - person L. Guthardt; 12.01.2018