Что делает «использование строгого» в JavaScript, и каковы причины этого?

7550

В последнее время , я побежал некоторые из моего кода JavaScript через Крокфорд в JSLint , и он дал следующее сообщение об ошибке:

Проблема в строке 1, символ 1: отсутствует выражение «использовать строгий».

Сделав поиск, я понял, что некоторые люди добавляют "use strict";в свой код JavaScript. Как только я добавил заявление, ошибка перестала появляться. К сожалению, Google не раскрыл большую часть истории этого строкового утверждения. Конечно, это как-то связано с тем, как браузер интерпретирует JavaScript, но я понятия не имею, каков будет эффект.

Так что же это такое "use strict";, что это означает и все еще актуально?

Кто-нибудь из текущих браузеров отвечает на "use strict";строку или это для будущего использования?

Марк Роджерс
источник
5
Ответы здесь старые, но они неправильные. Основным аргументом в пользу строгого режима было не предотвращать ошибки программирования - это было сделать лексическую область JavaScript так, чтобы она могла быть статически анализируемой:]
Бенджамин Грюнбаум
@BenjaminGruenbaum Использование "use strict";одного не делает JS лексически ограниченным. Объявление переменных с letи constдолжно использоваться тоже.
Коорош Пасохи
Вы смешиваете между областью видимости блока и лексической областью видимости.
Бенджамин Грюнбаум

Ответы:

4939

Эта статья о строгом режиме Javascript может вас заинтересовать: Джон Резиг - ECMAScript 5 Strict Mode, JSON и другие

Процитирую некоторые интересные части:

Строгий режим - это новая функция в ECMAScript 5, позволяющая поместить программу или функцию в «строгий» рабочий контекст. Этот строгий контекст предотвращает выполнение определенных действий и вызывает больше исключений.

А также:

Строгий режим выручает несколькими способами:

  • Он ловит некоторые распространенные ошибки кодирования, создавая исключения.
  • Он предотвращает или выдает ошибки, когда предпринимаются относительно «небезопасные» действия (например, получение доступа к глобальному объекту).
  • Это отключает функции, которые сбивают с толку или плохо продуманы.

Также обратите внимание, что вы можете применить «строгий режим» ко всему файлу ... Или вы можете использовать его только для определенной функции (все еще цитируя статью Джона Резига) :

// Non-strict code...

(function(){
  "use strict";

  // Define your library strictly...
})();

// Non-strict code... 

Что может быть полезно, если вам нужно смешать старый и новый код ;-)

Итак, я полагаю, что это немного похоже на "use strict"то, что вы можете использовать в Perl (отсюда и название?) : Оно помогает вам делать меньше ошибок, обнаруживая больше вещей, которые могут привести к поломкам.

Строгий режим теперь поддерживается всеми основными браузерами .

Внутри собственных модулей ECMAScript (с операторами importand export) и классов ES6 строгий режим всегда включен и не может быть отключен.

Паскаль МАРТИН
источник
100
Изменение по умолчанию через столько лет? Слишком поздно для этого: это сломало бы так много существующих сайтов / скриптов / приложений ... Единственное, что можно сделать, это помочь сделать вещи лучше в будущем.
Паскаль МАРТИН
14
Я попробовал небольшой фрагмент кода, который будет недействительным при использовании "use strict"в Firefox 3.6, Safari 5, Chrome 7 и Opera 10.6 (все Mac). Никаких ошибок, поэтому, я думаю, «использовать строгий» пока не поддерживается ни в одном браузере. Хотя не проверял в IE9;)
Husky
11
Быстрое обновление: Firefox 4 полностью поддерживает строгий режим, и, насколько я могу судить, ни один другой браузер не поддерживает его. Safari и Chrome имеют «частичную» поддержку, но я не знаю, что это значит.
Саша Чедыгов
29
Chrome 11, кажется, проходит все эти тесты, как и IE10 ie.microsoft.com/testdrive/HTML5/TryStrict/Default.html#
gman
12
@Julius - это не могло быть реализовано с использованием зарезервированного ключевого слова, потому что тогда код, пытающийся вызвать строгий режим, сломался бы в старых браузерах. Добавление «случайного» строкового литерала ничего не нарушает.
nnnnnn
1245

Это новая особенность ECMAScript 5. Джон Резиг написал хорошее резюме этого.

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

"use strict";

Размещение его в вашем коде сейчас не должно вызывать никаких проблем с текущими браузерами, так как это всего лишь строка. Это может вызвать проблемы с вашим кодом в будущем, если ваш код нарушает прагму. Например, если у вас в данный момент нет foo = "bar"определения fooсначала, ваш код начнет давать сбой ... что на мой взгляд хорошо.

Seth
источник
329
Быстро проваливайся и проваливайся громко.
Нильс Бом
31
Если вы пишете Javascript inline в файлах HTML, начинайте каждый новый блок с <script>"use strict";. Флаг применяется только к блоку, в который он включен.
Нобар
7
Забавно, в результате строки должны иметь одинарные кавычки. Так что пишите 'use strict';вместо
нильси
1
тогда что будет с концепцией подъема javascript?
Сунил Шарма
1
@SunilSharma Если вы попытаетесь поднять, но это не удастся, потому что переменная не определена, в данный момент она добавит ее в глобальный объект. С "use strict";, это не удастся вместо. Это имеет больше смысла, потому что если он добавляет его к глобальному объекту, это означает, что он может не сработать в следующий раз, когда вы запустите функцию / сделаете что-то еще, что сбрасывает блок, как это будет в самом высоком блоке (глобальном).
wizzwizz4
646

Эта инструкция "use strict";указывает браузеру использовать строгий режим, который представляет собой сокращенный и безопасный набор функций JavaScript.

Список функций (не исчерпывающий)

  1. Запрещает глобальные переменные. (Ловит пропущенные varобъявления и опечатки в именах переменных)

  2. Тихие неудачные задания приведут к ошибке в строгом режиме (назначение NaN = 5;)

  3. Попытки удалить неустранимые свойства бросят ( delete Object.prototype)

  4. Требует, чтобы все имена свойств в литерале объекта были уникальными ( var x = {x1: "1", x1: "2"})

  5. Имена параметров функции должны быть уникальными ( function sum (x, x) {...})

  6. Запрещает восьмеричный синтаксис ( var x = 023;некоторые разработчики ошибочно предполагают, что предыдущий ноль не меняет число.)

  7. Запрещает withключевое слово

  8. eval в строгом режиме не вводит новые переменные

  9. Запрещает удаление простых имен ( delete x;)

  10. Запрещает привязку или присвоение имен evalи argumentsв любой форме

  11. Строгий режим не связывает свойства argumentsобъекта с формальными параметрами. (то есть в function sum (a,b) { return arguments[0] + b;}этом работает, потому что arguments[0]связан с aи так далее.)

  12. arguments.callee не поддерживается

[Ссылка: строгий режим , Сеть разработчиков Mozilla ]

gprasant
источник
40
Примечание: глобальные переменные разрешены, просто должны быть явными (например window.foo = bar).
gcampbell
1
Требуется, чтобы все имена свойств в литерале объекта были уникальными (var x = {x1: "1", x1: "2"}), это допустимо
Арун Киллу
4
В вашем примере в 11 отсутствует модификация (иначе это не имеет смысла). И. е. сумма функций (a, b) {a = 0; вернуть аргументы [0] + b; } alert (sum (1, 2)) вернет 3 в строгом режиме и 2 без строгого режима из-за псевдонимов.
Дэвид Гаусманн
413

Если люди беспокоятся об использовании, use strictвозможно, стоит проверить эту статью:

ECMAScript 5 «Строгий режим» поддержка в браузерах. Что это значит?
NovoGeek.com - блог Кришны

В нем рассказывается о поддержке браузеров, но, что более важно, о том, как безопасно с ней обращаться:

function isStrictMode(){
    return !this;
} 
/*
   returns false, since 'this' refers to global object and 
   '!this' becomes false
*/

function isStrictMode(){   
    "use strict";
    return !this;
} 
/* 
   returns true, since in strict mode the keyword 'this'
   does not refer to global object, unlike traditional JS. 
   So here, 'this' is 'undefined' and '!this' becomes true.
*/
Джейми Хатбер
источник
116
Я не согласен. Я думаю, что это показывает, почему это очень полезно. По сути это означает, что это возвращает свою функцию, а неwindow
Джейми Хатбер
36
когда вам когда-нибудь понадобится окно, с thisкоторым вы не можете нацеливаться window?
Джейми Хатбер
14
Это относится к себе. thisпринадлежит своей функции, а не глобальному окну
Джейми Хатбер
26
Во втором thisдействительно есть undefined.
Broxzier
14
Дело в том, что ваша JS-программа начнет отказывать из-за доступа к свойству неопределенного, вместо того, чтобы молча делать неправильные вещи с глобальным объектом. Облегчает обнаружение мелких ошибок.
Стивен Чунг
208

Осторожно, всем вам, программистам с высокой нагрузкой: применение "use strict"к существующему коду может быть опасным! Это не какая-то приятная на ощупь наклейка с счастливым лицом, которую вы можете нанести на код, чтобы сделать его «лучше». С "use strict"прагмой, браузер внезапно будет БРОСАТЬ исключения в случайных местах, которые он никогда не генерировал раньше, просто потому, что в этот момент вы делаете что-то, что по умолчанию / свободный JavaScript разрешает, но строгий JavaScript не терпит! У вас могут быть нарушения строгости, скрывающие редко используемые вызовы в вашем коде, которые будут вызывать исключение, только когда они в конечном счете запускаются - скажем, в производственной среде, которую используют ваши платящие клиенты!

Если вы собираетесь сделать решающий шаг, это хорошая идея применять "use strict"наряду с комплексными модульными тестами и строго настроенной задачей сборки JSHint, которая даст вам некоторую уверенность в том, что в вашем модуле нет темного угла, который ужасно взорвется только потому, что вы включил строгий режим. Или, эй, вот еще один вариант: просто не добавляйте "use strict"ни один из ваших устаревших кодов, это, честно говоря, возможно, безопаснее. Определенно НЕ добавляйте "use strict"ни к каким модулям, которыми вы не владеете или не обслуживаете, например, к сторонним модулям.

Я думаю, что хотя это смертельно опасное животное, оно "use strict"может быть хорошим, но вы должны делать это правильно. Лучшее время для строгой оценки - это когда ваш проект находится на пустом месте, и вы начинаете с нуля. Сконфигурируйте JSHint/JSLintвсе предупреждения и параметры, как можно теснее, чтобы ваша команда смогла справиться с этим, получите хорошую систему сборки / тестирования / утверждения в виде фальшивых настроек Grunt+Karma+Chai, и только ТОГДА начните отмечать все ваши новые модули как "use strict". Будьте готовы вылечить множество ошибок и предупреждений. Убедитесь, что все понимают серьезность, настроив сборку на FAIL, если JSHint/JSLintвыдает какие-либо нарушения.

Мой проект не был новым проектом, когда я его принял "use strict". В результате моя среда IDE заполнена красными метками, потому что у меня нет "use strict"половины моих модулей, и JSHint жалуется на это. Это напоминание мне о том, что рефакторинг я должен делать в будущем. Моя цель - освободиться от красной метки из-за всех моих пропущенных "use strict"утверждений, но сейчас уже много лет.

DWoldrich
источник
24
ПОЧЕМУ разработчики в этой теме настолько кавалерны по поводу "строгого использования" ?? Ради всего святого, он отбрасывает ИСКЛЮЧЕНИЯ в иным образом работающем JavaScript ! Просто посыпьте его кодом, как сахар на кукурузных хлопьях, а? НЕТ! ПЛОХОЙ! «использовать строгое» следует использовать осторожно, желательно только в коде, которым вы управляете, который имеет модульные тесты, которые проходят во всех основных браузерах и которые осуществляют все пути кода. У тебя есть тесты? Ладно, "использовать строгий" - это хорошо для тебя, нокаути себя.
DWoldrich
57
Да. Очевидно, что «используйте строгий» может нарушить, казалось бы, действительный javascript, который раньше не нарушался. Но код, который ранее не был взломан, не равен правильному коду и выполнению того, для чего он предназначен. Обычно ссылка на необъявленные переменные сигнализирует об опечатке и т. Д. Использование строгого режима позволяет выявлять ошибки такого рода, и, надеюсь, перед отправкой рабочего кода.
Jostein Kjønigsen
5
... или просто примените «используйте строгий» как часть последнего прохода над вашим кодом, исправьте все очевидные проблемы, пожмите плечами, скажите «достаточно хорошо», а затем выньте его для производства :)
Wolfie Inu
13
Лично я никогда / очень редко добавляю "use strict"; в существующий код. При этом я почти всегда буду использовать его, когда пишу новый код с нуля
Martin
3
Если вы уже используете JSLint, вы, вероятно, исправили большинство мест, где «использование строгого» может привести к поломке.
Джонатан В ролях
179

Использование 'use strict';не делает ваш код лучше.

Строгий режим JavaScript особенность в ECMAScript 5 . Вы можете включить строгий режим, объявив это в верхней части вашего скрипта / функции.

'use strict';

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

Рассмотрим этот пример:

var a = 365;
var b = 030;

В своем стремлении выстроить числовые литералы разработчик непреднамеренно инициализировал переменную bс восьмеричным литералом. Нестрогий режим интерпретирует это как числовой литерал со значением 24(в базе 10). Однако строгий режим выдаст ошибку.

Неисчерпывающий список специальностей в строгом режиме см. В этом ответе .


Где я должен использовать 'use strict';?

  • В моем новом приложении JavaScript: Абсолютно! Строгий режим может использоваться в качестве информатора, когда вы делаете что-то глупое с вашим кодом.

  • В моем существующем коде JavaScript: вероятно, нет! Если в вашем существующем коде JavaScript есть операторы, которые запрещены в строгом режиме, приложение просто сломается. Если вы хотите строгий режим, вы должны быть готовы к отладке и исправлению существующего кода. Вот почему использование 'use strict';не делает ваш код лучше .


Как использовать строгий режим?

  1. Вставьте 'use strict';оператор поверх вашего скрипта:

    // File: myscript.js
    
    'use strict';
    var a = 2;
    ....

    Обратите внимание, что все в файле myscript.jsбудет интерпретироваться в строгом режиме.

  2. Или вставьте 'use strict';оператор поверх тела вашей функции:

    function doSomething() {
        'use strict';
        ...
    }

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


Какие вещи запрещены в строгом режиме?

Я нашел хорошую статью, описывающую несколько вещей, которые запрещены в строгом режиме (обратите внимание, что это не эксклюзивный список):

Объем

Исторически JavaScript был сбит с толку о том, как функции ограничены. Иногда они кажутся статически ограниченными, но некоторые функции заставляют их вести себя так, как будто они динамически ограничены. Это сбивает с толку, затрудняя чтение и понимание программ. Непонимание вызывает ошибки. Это также является проблемой для производительности. Статическая область видимости позволила бы связывание переменных во время компиляции, но требование динамической области действия означает, что связывание должно быть отложено до времени выполнения, что приводит к значительному снижению производительности.

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

Одним из преимуществ строгого кода является то, что такие инструменты, как YUI Compressor, могут лучше обрабатывать его.

Подразумеваемые глобальные переменные

JavaScript подразумевает глобальные переменные. Если вы явно не объявляете переменную, глобальная переменная неявно объявляется для вас. Это облегчает программирование для начинающих, потому что они могут пренебречь некоторыми из своих основных дел по дому. Но это значительно усложняет управление большими программами и значительно снижает надежность. Таким образом, в строгом режиме подразумеваемые глобальные переменные больше не создаются. Вы должны явно объявить все ваши переменные.

Глобальная утечка

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

Шумный отказ

JavaScript всегда имел свойства только для чтения, но вы не можете создавать их самостоятельно, пока Object.createProperty функция ES5 не продемонстрирует эту возможность. Если вы попытаетесь присвоить значение свойству только для чтения, оно молча завершится неудачей. Назначение не изменит значение свойства, но ваша программа будет работать так, как если бы это было. Это угроза целостности, которая может привести к тому, что программы перейдут в несовместимое состояние. В строгом режиме попытка изменить свойство только для чтения вызовет исключение.

восьмеричный

Восьмеричное (или базовое 8) представление чисел было чрезвычайно полезно при программировании на уровне машины на машинах с размерами слов, кратными 3. Вам нужно восьмеричное значение при работе с мэйнфреймом CDC 6600, который имел размер слова 60 бит. Если бы вы могли читать восьмеричное, вы могли бы смотреть на слово как 20 цифр. Две цифры представляют код операции, а одна цифра обозначает один из 8 регистров. Во время медленного перехода от машинных кодов к языкам высокого уровня считалось полезным предоставить восьмеричные формы в языках программирования.

В C было выбрано крайне неудачное представление восьмеричности: ведущий ноль. Таким образом, в C 0100означает 64, а не 100, и 08является ошибкой, а не 8. Более того, к сожалению, этот анахронизм был скопирован почти на все современные языки, включая JavaScript, где он используется только для создания ошибок. У него нет другой цели. Так что в строгом режиме восьмеричные формы больше не разрешены.

И так далее

Псевдомассив arguments становится более похожим на массив в ES5. В строгом режиме, она теряет свое calleeи caller свойство. Это позволяет передать ваш argumentsненадежный код, не отказываясь от большого количества конфиденциального контекста. Также argumentsисключено свойство функций.

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


Зарезервированные слова для будущих версий JavaScript

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

implements, interface, let, package, private, protected, public, static, Иyield


Дальнейшее чтение

sampathsris
источник
2
это очень хорошее объяснение. Однако у меня есть одно сомнение в том, что я могу использовать «строгий» режим в сочетании с другими библиотеками java-скриптов, такими как Angular js?
UVM
3
@UVM: директива строгого режима влияет только на лексическую область видимости. т.е. только файл / функция, в которой он объявлен. Если у вас есть другой файл / функция, у которой нет 'use strict'директивы, они будут выполняться в нестрогом режиме, даже если они вызваны из функции, работающей в строгом режиме. Смотрите этот ответ для объяснения.
Сампатрисрис
Это не совсем правильно. 'use strict' меняет способ выполнения кода.
CyberEd
3
На второй взгляд, ты прав. Я думал, что вы имели в виду, что это только вызывает исключения, но не изменило способ работы кода (например, изменение this). Теперь я вижу, что вы имели в виду вызов других функций.
CyberEd
3
В некоторых случаях восьмеричное полезно. Синтаксис C для него ужасен, но мне бы хотелось, чтобы языки добавили новый восьмеричный синтаксис, который мог бы позволить исключить форму начального нуля. Конечно, для Javascript поддерживать форму с начальным нулем было просто глупо.
суперкат
138

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

По-видимому, на начальном этапе будут ошибки, с которыми мы никогда не сталкивались. Чтобы получить максимальную выгоду, мы должны провести надлежащее тестирование после перехода в строгий режим, чтобы убедиться, что мы все поймали. Определенно, мы не просто добавляем use strictнаш код и предполагаем, что ошибок нет. Таким образом, проблема в том, что пришло время начать использовать эту невероятно полезную языковую функцию для написания лучшего кода.

Например,

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint - это отладчик, написанный Дугласом Крокфордом. Просто вставьте ваш скрипт, и он быстро отыщет любые заметные проблемы и ошибки в вашем коде.

Панк
источник
6
@JamieHutber: перейдите по этой ссылке caniuse.com/use-strict AND kangax.github.io/es5-compat-table . Это даст точное представление для всего браузера.
Pank
95

Я хотел бы предложить несколько более обоснованный ответ, дополняющий другие ответы. Я надеялся отредактировать самый популярный ответ, но не смог. Я постарался сделать его как можно более полным и полным.

Вы можете обратиться к документации MDN для получения дополнительной информации.

"use strict" Директива введена в ECMAScript 5.

Директивы похожи на заявления, но отличаются.

  • use strictне содержит ключевых слов: директива представляет собой простое выражение выражения, которое состоит из специального строкового литерала (в одинарных или двойных кавычках). Механизмы JavaScript, которые не реализуют ECMAScript 5, просто видят выражение-выражение без побочных эффектов. Ожидается, что будущие версии стандартов ECMAScript будут представлены useкак реальное ключевое слово; таким образом, цитаты устаревают.
  • use strictможет использоваться только в начале скрипта или функции, то есть он должен предшествовать любому другому (реальному) утверждению. Это не обязательно должна быть первая инструкция в скрипте функции: ей могут предшествовать другие операторные выражения, которые состоят из строковых литералов (и реализации JavaScript могут рассматривать их как директивы, специфичные для реализации). Операторы строковых литералов, которые следуют за первым реальным оператором (в скрипте или функции), являются простыми операторами выражения. Переводчики не должны интерпретировать их как директивы, и они не имеют никакого эффекта.

use strictДиректива указывает , что следующий код (в сценарии или функции) строгий код. Код на самом высоком уровне сценария (код, который отсутствует в функции) считается строгим кодом, когда сценарий содержит use strictдирективу. Содержимое функции считается строгим кодом, если сама функция определена в строгом коде или когда функция содержит use strictдирективу. Код, который передается eval()методу, считается строгим кодом, когда вызывается eval()из строгого кода или содержит use strictсаму директиву.

Строгий режим ECMAScript 5 является ограниченным подмножеством языка JavaScript, что устраняет соответствующие недостатки языка и обеспечивает более строгую проверку ошибок и более высокий уровень безопасности. Ниже перечислены различия между строгим режимом и обычным режимом (из которых первые три особенно важны):

  • Вы не можете использовать with-statement в строгом режиме.
  • В строгом режиме все переменные должны быть объявлены: если вы присваиваете значение идентификатору, который не был объявлен как переменная, функция, параметр функции, параметр catch-clause или свойство global Object, то вы получите a ReferenceError. В обычном режиме идентификатор неявно объявляется как глобальная переменная (как свойство глобальной Object)
  • В строгом режиме ключевое слово thisимеет значение undefinedв функциях, которые вызывались как функции (а не как методы). (В обычном режиме thisвсегда указывает на глобальный Object). Это различие можно использовать для проверки, поддерживает ли реализация строгий режим:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Кроме того, когда функция вызывается в строгом режиме call()или applyв строгом режиме, thisэто точно значение первого аргумента вызова call()or apply(). (В нормальном режиме nullи undefinedзаменяются глобальной Objectи значениями, которые не являются объектами, отлиты в объекты.)

  • В строгом режиме вы получите TypeError, когда вы попытаетесь присвоить только для чтения свойства или определить новые свойства для нерасширяемого объекта. (В обычном режиме оба просто терпят неудачу без сообщения об ошибке.)

  • В строгом режиме при передаче кода eval()вы не можете объявлять или определять переменные или функции в области действия вызывающей стороны (как вы можете сделать это в обычном режиме). Вместо этого создается новая область действия, eval()а переменные и функции находятся в этой области. Эта область уничтожается после eval()завершения выполнения.
  • В строгом режиме объект arguments объекта содержит статическую копию значений, которые передаются этой функции. В обычном режиме объект arguments имеет несколько «магическое» поведение: элементы массива и параметры именованной функции ссылаются на одно и то же значение.
  • В строгом режиме вы получите, SyntaxErrorкогда за deleteоператором следует неквалифицированный идентификатор (переменная, функция или параметр функции). В обычном режиме deleteвыражение ничего не делает и оценивается как false.
  • В строгом режиме вы получите, TypeErrorкогда вы попытаетесь удалить не настраиваемое свойство. (В обычном режиме попытка просто терпит неудачу, и deleteвыражение оценивается как false).
  • В строгом режиме это считается синтаксической ошибкой, когда вы пытаетесь определить несколько свойств с одним и тем же именем для литерала объекта. (В обычном режиме ошибки нет.)
  • В строгом режиме это считается синтаксической ошибкой, когда объявление функции имеет несколько параметров с одинаковым именем. (В обычном режиме ошибки нет.)
  • В строгом режиме восьмеричные литералы не допускаются (это литералы, начинающиеся с 0x. (В нормальном режиме некоторые реализации допускают восьмеричные литералы.)
  • В строгом режиме идентификаторы evalи argumentsобрабатываются как ключевые слова. Вы не можете изменить их значение, не можете присвоить им значение и не можете использовать их в качестве имен для переменных, функций, параметров функций или идентификаторов блока catch.
  • В строгом режиме больше ограничений на возможности изучения стека вызовов. arguments.callerи arguments.calleeвызвать TypeErrorфункцию в строгом режиме. Кроме того, некоторые свойства вызывающего и аргумента функций в строгом режиме вызывают, TypeErrorкогда вы пытаетесь их прочитать.
Ely
источник
4
«В строгом режиме восьмеричные литералы недопустимы (это литералы, начинающиеся с 0x ...)» восьмеричные литералы начинаются с лидирующего 0.
Алекс Гиттемайер
83

Мои два цента:

Одна из целей строгого режима - обеспечить более быструю отладку проблем. Это помогает разработчикам, создавая исключения, когда происходят определенные неправильные вещи, которые могут вызвать тихое и странное поведение вашей веб-страницы. Момент мы используемuse strict код, он выдает ошибки, которые помогают разработчику заранее исправить это.

Несколько важных вещей, которые я узнал после использования use strict:

Предотвращает объявление глобальной переменной:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

Теперь этот код создается nameoftreeв глобальной области видимости, к которой можно получить доступ с помощью window.nameoftree. Когда мы реализуем use strictкод будет выдавать ошибку.

Uncaught ReferenceError: nameoftree не определено

Sample

Исключает withутверждение:

withоператоры не могут быть уменьшены с помощью таких инструментов, как uglify-js . Они также устарели и удалены из будущих версий JavaScript.

Sample

Предотвращает дубликаты:

Когда у нас есть повторяющееся свойство, оно выдает исключение

Uncaught SyntaxError: Дублирование свойства данных в литерале объекта не допускается в строгом режиме

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

Их немного, но мне нужно больше узнать об этом.

Shubh
источник
С ECMAScript 2015 повторные имена свойств снова разрешены! Смотрите документацию MDN .
Филмколе
62

Если вы используете браузер, выпущенный в прошлом году или около того, то, скорее всего, он поддерживает строгий режим JavaScript. Только старые браузеры до того, как ECMAScript 5 стал текущим стандартом, не поддерживают его.

Кавычки вокруг команды гарантируют, что код будет по-прежнему работать и в старых браузерах (хотя вещи, которые генерируют синтаксическую ошибку в строгом режиме, как правило, просто приводят к сбоям в работе сценария, что трудно обнаружить в старых браузерах).

Стивен
источник
12
Тогда что это делает?
Аниш Гупта
7
... это частично описывает совместимость, но не то, что на самом деле.
courtimas
58

При добавлении "use strict";следующие случаи будут выдавать SyntaxError перед выполнением сценария:

  • Прокладывая путь для версий будущего ECMAScript , используя один из недавно зарезервированных ключевых слов (в предвидении для ECMAScript 6 ): implements, interface, let, package, private, protected, public, static, и yield.

  • Объявление функции в блоках

    if(a<b){ function f(){} }
  • Восьмеричный синтаксис

    var n = 023;
  • this указать на глобальный объект.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
  • Объявление дважды одинакового имени для имени свойства в литерале объекта

     {a: 1, b: 3, a: 7} 

    Это больше не относится к ECMAScript 6 ( ошибка 1041128 ).

  • Объявление двух аргументов функции с одинаковым именем функции

    f(a, b, b){}
  • Установка значения в необъявленную переменную

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
  • Использование deleteпо имени переменнойdelete myVariable;

  • Использование evalили в argumentsкачестве имени переменной или аргумента функции

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 

Источники:

zangw
источник
С ECMAScript 2015 повторные имена свойств снова разрешены! Смотрите документацию MDN .
Филмколе
53

Строгий режим вносит несколько изменений в обычную семантику JavaScript:

  • устраняет некоторые тихие ошибки JavaScript, изменяя их на ошибки.

  • исправляет ошибки, мешающие движкам JavaScript выполнять оптимизацию.

  • запрещает некоторый синтаксис, который может быть определен в будущих версиях ECMAScript.

для получения дополнительной информации vistit строгий режим - Javascript

Ренганатан М.Г.
источник
52

«Строгое использование»; является гарантией того, что программист не будет использовать плохие или плохие свойства JavaScript. Это руководство, так же, как правитель поможет вам сделать прямые линии. «Use Strict» поможет вам сделать «прямое кодирование».

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

Поверь мне. Издержки незначительны по сравнению с плохо разработанным кодом. У Дуга Крокфорда, который несколько лет был старшим разработчиком JavaScript, есть очень интересный пост . Лично мне нравится все время возвращаться на его сайт, чтобы не забыть свою хорошую практику.

Современная практика JavaScript всегда должна вызывать «Use Strict»; Прагма. Единственная причина, по которой группа ECMA сделала необязательный режим «Строгий», заключается в том, чтобы предоставить менее опытным кодировщикам доступ к JavaScript и дать время для адаптации к новым и более безопасным методам кодирования.

user2436758
источник
66
Причина, по которой строгий режим является необязательным, не имеет ничего общего с тем, что вы заявили. Настоящая причина - не нарушать существующий код, который может не соответствовать .
кислород
17
Действительно, менее опытные программисты должны быть первыми , кто разрешит «строгое использование»;
Антти Хаапала
46

Включение use strictв начало всех ваших чувствительных файлов JavaScript с этой точки зрения является небольшим способом стать лучшим программистом JavaScript и избежать случайного изменения глобальных переменных и изменений в молчании.

Заполнитель
источник
42

Цитирование из w3schools :

Директива об использовании строгих правил

Директива «use strict» появилась в JavaScript 1.8.5 (ECMAScript версии 5).

Это не утверждение, а буквальное выражение, игнорируемое более ранними версиями JavaScript.

Цель «использования строгого» - указать, что код должен выполняться в «строгом режиме».

В строгом режиме нельзя, например, использовать необъявленные переменные.

Почему строгий режим?

Строгий режим облегчает написание «безопасного» JavaScript.

Строгий режим изменяет ранее принятый «плохой синтаксис» на реальные ошибки.

Например, в обычном JavaScript неправильный ввод имени переменной создает новую глобальную переменную. В строгом режиме это вызовет ошибку, из-за которой невозможно случайно создать глобальную переменную.

В обычном JavaScript разработчик не будет получать никаких сообщений об ошибках, присваивая значения свойствам, недоступным для записи.

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

Пожалуйста, обратитесь к http://www.w3schools.com/js/js_strict.asp, чтобы узнать больше

Heich-Б
источник
37

"use strict"заставляет код JavaScript работать в строгом режиме , что в основном означает, что все должно быть определено перед использованием. Основная причина использования строгого режима состоит в том, чтобы избежать случайного глобального использования неопределенных методов.

Также в строгом режиме все работает быстрее, некоторые предупреждения или тихие предупреждения приводят к фатальным ошибкам, лучше всегда использовать его для создания более аккуратного кода.

"use strict"широко используется в ECMA5, в ECMA6 по умолчанию он является частью JavaScript , поэтому его не нужно добавлять, если вы используете ES6.

Посмотрите на эти заявления и примеры из MDN:

Директива «использовать строгое» Директива
«использовать строгое» появилась в JavaScript 1.8.5 (версия 5 ECMAScript). Это не утверждение, а буквальное выражение, игнорируемое более ранними версиями JavaScript. Цель «использования строгого» - указать, что код должен выполняться в «строгом режиме». В строгом режиме нельзя, например, использовать необъявленные переменные.

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

1) строгий режим в функциях

 function strict() {
     // Function-level strict mode syntax
     'use strict';
     function nested() { return 'And so am I!'; }
     return "Hi!  I'm a strict mode function!  " + nested();
 }
 function notStrict() { return "I'm not strict."; }

 console.log(strict(), notStrict());

2) строгий режим всего сценария

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3) Присвоение неписываемым глобальным

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

Вы можете прочитать больше на MDN .

Алиреза
источник
31

Некоторые люди, которые были в комитете ECMAScript, говорили о том, как меняется JavaScript, часть 1: ECMAScript 5, о том, как постепенно использовать"use strict" переключателя позволяет разработчикам JavaScript очищать многие опасные функции JavaScript без внезапного взлома каждого веб-сайта. в мире.

Разумеется, в нем также говорится о том, чем являются (были) многие из этих ошибок, и как ECMAScript 5 их исправляет.

FutureNerd
источник
27

Небольшие примеры для сравнения:

Нестрогий режим:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

Строгий режим:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

Нестрогий режим:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true

Tân
источник
2
Обратите внимание, что приведенный выше код добавит переменную i в глобальную область (обычно это не лучшая практика, и строгий режим помогает избежать этого).
Майкл
1
Может кто-нибудь объяснить второй пример? Я не понимаю Не должно this === 'a'в обоих примерах?
MaximeW
19

Обратите внимание, что use strictбыл введен в EcmaScript 5 и сохранился с тех пор.

Ниже приведены условия для запуска строгого режима в ES6 и ES7 :

  • Глобальный код является кодом строгого режима, если он начинается с Пролога Директивы, который содержит Директиву строгого использования (см. 14.1.1).
  • Код модуля - это всегда строгий код режима.
  • Все части ClassDeclaration или ClassExpression являются строгим кодом режима.
  • Eval-код - это код строгого режима, если он начинается с Пролога директивы, который содержит директиву Use Strict, или если вызов eval является прямым eval (см. 12.3.4.1), который содержится в коде строгого режима.
  • Код функции - это код строгого режима, если связанный код FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition или ArrowFunction содержится в коде строгого режима или если код, который создает значение внутреннего слота функции [[ECMAScriptCode]], начинается с директивного пролога который содержит директиву об использовании строго.
  • Код функции, который предоставляется в качестве аргументов для встроенных конструкторов Function и Generator, является кодом строгого режима, если последний аргумент является строкой, которая при обработке является FunctionBody, которая начинается с пролога директивы, содержащей директиву Use Strict.
Ориоль
источник
14

Основные причины, по которым разработчики должны использовать "use strict"это:

  1. Предотвращает случайное объявление глобальных переменных. Использование "use strict()"гарантирует, что переменные объявлены varперед использованием. Например:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
  2. NB. "use strict"Директива распознается только в начале скрипта или функции.
  3. Строка "arguments"не может быть использована в качестве переменной:

    "use strict";
    var arguments = 3.14;    // This will cause an error
  4. Ограничит использование ключевых слов в качестве переменных. Попытка использовать их приведет к ошибкам.

Короче говоря, ваш код будет менее подвержен ошибкам и, в свою очередь, заставит вас писать хороший код.

Чтобы узнать больше об этом вы можете обратиться сюда .

Притам Банерджи
источник
12

«использовать строгое»; является попыткой ECMA сделать JavaScript немного более надежным. Это привносит в JS попытку сделать его хотя бы немного «строгим» (другие языки применяют строгие правила с 90-х годов). Это на самом деле «заставляет» разработчиков JavaScript следовать некоторым рекомендациям по кодированию. Тем не менее, JavaScript очень хрупкий. Не существует таких вещей, как типизированные переменные, типизированные методы и т. Д. Я настоятельно рекомендую разработчикам JavaScript изучать более надежный язык, такой как Java или ActionScript3, и применять те же самые лучшие практики в своем коде JavaScript, это будет работать лучше и легче отладки.

PippoApps.com
источник
12

«Строгий» режим JavaScript был введен в ECMAScript 5.

(function() {
  "use strict";
  your code...
})();

Запись "use strict";в самом верху вашего файла JS включает строгую проверку синтаксиса. Он выполняет следующие задачи для нас:

  1. показывает ошибку, если вы пытаетесь присвоить необъявленную переменную

  2. останавливает перезапись ключевых системных библиотек JS

  3. запрещает некоторые небезопасные или подверженные ошибкам языковые функции

use strictтакже работает внутри отдельных функций. Всегда лучше включать use strictв свой код.

Проблема совместимости браузера: директивы use предназначены для обратной совместимости. Браузеры, которые их не поддерживают, просто увидят строковый литерал, на который больше нет ссылок. Итак, они пройдут над ним и пойдут дальше.

Рабин Панта
источник
12

use strictэто способ сделать ваш код более безопасным, потому что вы не можете использовать опасные функции, которые могут работать не так, как вы ожидаете. И, как было написано ранее, это делает код более строгим.

Просто программист
источник
11

Use Strict используется для отображения распространенных и повторяющихся ошибок, так что он обрабатывается по-разному и изменяет способ выполнения сценария Java, такие изменения:

  • Предотвращает случайные глобалы

  • Без дубликатов

  • Устраняет с

  • Устраняет это принуждение

  • Более безопасный eval ()

  • Ошибки для неизменяемых

Вы также можете прочитать эту статью для деталей

Wesam
источник
11

Обычно JavaScript не следует строгим правилам, что увеличивает вероятность ошибок. После использования "use strict"код JavaScript должен следовать строгому набору правил, как и в других языках программирования, таких как использование терминаторов, объявление перед инициализацией и т. Д.

Если "use strict"используется, код должен быть написан в соответствии со строгим набором правил, следовательно, уменьшается вероятность ошибок и неясностей.

Бикаш Чапагайн
источник
7

«использовать строгое»; Определяет, что код JavaScript должен выполняться в «строгом режиме».

  • Директива «Use strict» была впервые введена в ECMAScript версии 5.
  • Это не утверждение, а буквальное выражение, игнорируемое более ранними версиями JavaScript.
  • Цель «использования строгого» - указать, что код должен выполняться в «строгом режиме».
  • В строгом режиме нельзя, например, использовать необъявленные переменные.

Все современные браузеры поддерживают «строгое использование», кроме Internet Explorer 9 и ниже .

Недостаток

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

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

Кроме того, как указано выше, строгий режим не позволяет вам делать определенные вещи.

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

Ashish
источник
4

Строгий режим может предотвратить утечки памяти.

Пожалуйста, проверьте функцию ниже, написанную в нестрогом режиме:

function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); // Stack Overflow

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

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


Теперь давайте напишем ту же функцию в строгом режиме.

"use strict"
function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); 

Мы получим следующую ошибку.

Uncaught ReferenceError: name is not defined
at getname (<anonymous>:3:15)
at <anonymous>:6:5

Здесь компилятор выдает ошибку ссылки. В строгом режиме компилятор не позволяет нам использовать переменную без ее объявления. Таким образом, утечки памяти могут быть предотвращены. Кроме того, мы можем написать более оптимизированный код.

Джерин К Александр
источник