Для чего используется строгий режим в js. Как строгий режим "use strict" в JavaScript может сэкономить вам пару часов

Эта директива пишется в начале сценария или функции. Так и пишется:

И для чего же она нужна? Все что ниже директивы "use strict" , является строгим кодом. Строгий, это код, написанный по новому стандарту. Например, в старом стандарте можно было не объявлять переменную, а в новом нужно объявлять.

"use strict";
a = 10; // Ошибка: переменная не объявлена
document.write(a);

А так будет работать, если объявить переменную:

Var a;
"use strict";
a = 10;
document.write(a);

Эти пункты взяты из книги: "Дэвид Флэнаган - JavaScript. Подробное руководство (6-е издание)"

  • В строгом режиме не допускается использование инструкции with .
  • В строгом режиме все переменные должны объявляться: если попытаться присвоить значение идентификатору, который не является объявленной переменной, функцией, параметром функции, параметром конструкции catch или свойством глобального объекта, возбуждается исключение ReferenceError . (В нестрогом режиме такая попытка просто создаст новую глобальную переменную и добавит ее в виде свойства в глобальный объект.)
  • В строгом режиме функции, которые вызываются как функции (а не как методы), получают в ссылке this значение undefined . (В нестрогом режиме функции, которые вызываются как функции, всегда получают в ссылке this глобальный объект.) Это отличие можно использовать, чтобы определить, поддерживает ли та или иная реализация строгий режим: var hasStrictMode = (function() { "use strict"; return this===undefined}()); Кроме того, когда функция вызывается в строгом режиме с помощью call() или apply() , значение ссылки this в точности соответствует значению, переданному в первом аргументе функции call() или apply() . (В нестрогом режиме значения null и undefined замещаются ссылкой на глобальный объект, а простые значения преобразуются в объекты.)
  • В строгом режиме попытки присвоить значения свойствам, недоступным для записи, или создать новые свойства в нерасширяемых объектах порождают исключение TypeError . (В нестрогом режиме эти попытки просто игнорируются.)
  • В строгом режиме программный код, передаваемый функции eval() , не может объявлять переменные или функции в области видимости вызывающего программного кода, как это возможно в нестрогом режиме. Вместо этого переменные и функции помещаются в новую область видимости, создаваемую для функции eval() . Эта область видимости исчезает, как только eval() вернет управление.
  • В строгом режиме объект arguments в функции хранит статическую копию значений, переданных функции. В нестрогом режиме объект arguments ведет себя иначе – элементы массива arguments и именованные параметры функции ссылаются на одни и те же значения.
  • В строгом режиме возбуждается исключение SyntaxError , если оператору delete передать неквалифицированный идентификатор, такой как имя переменной, функции или параметра функции. (В нестрогом режиме такое выражение delete не выполнит никаких действий и вернет false .)
  • В строгом режиме попытка удалить ненастраиваемое свойство приведет к исключению TypeError . (В нестрогом режиме эта попытка просто завершится неудачей и выражение delete вернет false .)
  • В строгом режиме попытка определить в литерале объекта два или более свойств с одинаковыми именами считается синтаксической ошибкой. (В нестрогом режиме ошибка не возникает.)
  • В строгом режиме определение двух или более параметров с одинаковыми именами в объявлении функции считается синтаксической ошибкой. (В нестрогом режиме ошибка не возникает.)
  • В строгом режиме не допускается использовать литералы восьмеричных целых чисел (начинающихся с 0, за которым не следует символ x). (В нестрогом режиме некоторые реализации позволяют использовать восьмеричные литералы.)
  • В строгом режиме идентификаторы eval и arguments интерпретируются как ключевые слова, и вы не можете изменить их значения. Вы сможете присвоить значения этим идентификаторам, объявив их как переменные, использовав их в качестве имен функций, имен параметров функций или идентификаторов блока catch .
  • В строгом режиме ограничивается возможность просмотра стека вызовов. Попытки обратиться к свойствам arguments.caller arguments.callee и в строгом режиме возбуждают исключение TypeError . Попытки прочитать свойства caller и arguments функций в строгом режиме также возбуждают исключение TypeError . (Некоторые реализации определяют эти свойства в нестрогих функциях.)

(далее в статье Strict Mode). Strict Mode накладывает слой ограничений на JavaScript, он отгораживает вас от опасных частей языка (те части, которые есть исторически, но лучше чтобы их не было) и позволяет снизить вероятность ошибки.

Пока читал эту статью я написал 38 тестов, покрывающих все правила Strict Mode, объявленные в спецификации ES5. Вы можете посмотреть насколько ваш браузер поддерживает эти справила .

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

Firefox 4 уже полностью поддерживает Strict Mode, а Chrome 11 практически полностью. Strict Mode уже не за горами - давайте изучим его подробнее!

Как включить Strict Mode? Если добавить "use strict" в начало вашего JavaScript кода, то Strict Mode будет применен для всего кода:
"use strict"; 012; //Восьмеричный литерал запрешен. Выбросит исключение SyntaxError в Strict Mode
В качестве альтернативы вы можете включить Strict Mode только в отдельной функции, добавив "use strict" в начало тела вашей функции:
012; //Нет ошибки (Strict Mode не включен глобально) function foo() { "use strict"; x=3; //Strict Mode выбросит исключение - запрещено неявно создавать глобальные переменные } foo(); //ReferenceError (Strict Mode включен для функции) Наследуют ли внутренние функции Strict Mode от внешних функций? Внутренняя функция, объявленная внутри внешней, в которой включен Strict Mode тоже будет иметь Strict Mode:
var wrapper = function(fn) { "use strict"; var deleteNonConfigurable = function () { var obj = {}; Object.defineProperty(obj, "name", { configurable: false }); delete obj.name; // Выбросит исключение TypeError в Strict Mode } return deleteNonConfigurable; } wrapper()(); //TypeError (Strict Mode включен)
Важно запомнить, что Strict Mode не распространяется на «нестрогие» (ориг. non-strict) функции, которые выполняются внутри строгой функции (или они отправлены в функцию в качестве аргументов или выполняются, используя call или apply):
var test = function(fn) { "use strict"; fn(); } var deleteNonConfigurable = function () { var obj = {}; Object.defineProperty(obj, "name", { configurable: false }); delete obj.name; // Выбросит исключение TypeError в Strict Mode } test(deleteNonConfigurable); //нет ошибки (Strict Mode не применялся) Почему я не могу включить Strict Mode в консоли моего браузера? Когда выполняешь код в консоли фаербага или в других консолях использование "use strict" вне функции не имеет силы. Это потому, что большинство консолей обрамляют ваш код в eval"ом, поэтому ваш "use strict" не является первым выражением. Это можно обойти, обрамив ваш код в замыкание (IIFE), в начало которого мы положим "use strict" (но, когда я тестировал такой способ включения Strict Mode я понял, что это довольно неудобно, особенно если работать в консоли webkit developer tools - лучше тестировать ваш код на странице):
(function() { "use strict"; var a; var b; function bar() { x = 5; //Strict Mode выбросит исключение за попытку создания глобальной переменной } bar(); // ReferenceError (Strict Mode включен) })(); Что произойдет если мой браузер не поддерживает Strict Mode? Ничего. Директива "use strict" это обычное строковое выражение, которое будет проигнорировано всеми движками JavaScript, которые не поддерживают Strict Mode. Это позволяет безопасно использовать синтаксис Strict Mode во всех браузерах без каких-либо опасений, в то время когда браузеры имеющие поддержку Strict Mode будут использовать его.Какие правила включены в Strict Mode? Правила определены в спецификации Strict Mode и включают в себя ограничения во время «компиляции» и интерпретации (выполнения скрипта). Это вводный обзор (каждое правило я описал с примерами в следующем параграфе): ecma262-5.com/ELS5_HTML.htm#Annex_C Синтаксические ошибки Syntax Errors В большинстве случаев Strict Mode предотвращает выполнение подозрительного или нелегального кода в процессе загрузки. Восьмеричные числа, дубли имен переменных, некорректное использование delete и попытки сделать что-нибудь этакие с eval и ключевым словом arguments, использование with приведет к исключению SyntaxError.Слово this В Strict Mode объект this не будет корректироваться. Это возможно самая интересная часть Strict Mode и самая тяжелая(шокирующая) для разработчиков. Все знают, что если первый аргумент call или apply - null или undefined, то значение this выполняемой функции будет преобразование в глобальный объект (для браузеров это window).Прямое создание глобальных переменных Не все согласятся с этим, но непрямое создание глобального объекта почти всегда является ошибкой. В Strict Mode вам выдадут красную карточку - ReferenceError.arguments.caller и arguments.callee Эти «полезные свойства» (от пер. никогда не применял их) запрещены в Strict Mode. Если вы используете их в вашем кода, то Strict Mode выбросит исключение.Объявление существующего имени объекта Когда вы создаете объект с двумя одинаковыми ключами, то Strict Mode выбросит исключение TypeError.Тесты Вот исходник моих Strict Mode тестов. Каждый набор тестов снабжен комментарием, ссылающемся на часть спецификации ECMAScript, которую он тестирует. Эта версия может быть выполнена в «режиме консоли». Т.е. вы можете скопировать тест, вставить в консоль и выполнить без изменений. Этот же код, работающий в режиме «HTML» я использовал для создания тестовой страницы, которую я представил вам в начале статьи. Этот исходник с дополнительными объектами в моем github репозитории . Я уверен, что там есть пара ошибок - не стесняйтесь присылать ошибки!

От переводчика: тут в статье шел огромный кусок кода, закинул его на pastebin

Заключение Запрещение обращение к некоторым возможностям языка для улучшения кода - вопрос спорный, давайте отложим эти споры. В защиту Strict Mode я хочу сказать, что это отличный компромисс между тотальными переменами (которые сломают обратную совместимость) и ничего не деланием (которое приведет к захламлению языка и научит разработчиков плохому). ECMA-262 5th Edition: The Strict Mode of ECMAScript
Asen Bozhilov: Strict tester
Таблица совместимости с ECMAScript 5, часть посвященная Strict mode . Это отличный источник, часть большой таблицы совместимости, разработанной Юрием Зайцевым (Juriy Zaytsev aka «kangax»)

От переводчика. Strict Mode поддерживают практически половина всех браузеров, кроме своих прекрасных ограничений и иммунитету к распространенным ошибкам Strict Mode дает и другие преимущества (статья mraleph). Скоро неиспользование Strict Mode станет плохим тоном (аналогично requestAnimationFrame vs setTimeout). Сейчас самое время начать эксперименты!

Строгий режим (директива "use strict") - очень хорошее явление в JavaScript и начать с ним работать очень просто!

Как его применить // file.js "use strict" function doStuff () { // строгий режим активирован }

В описанном выше примере строгий режим применяется по всему коду в файле file.js .

Если вы хотите подключить его только внутри функции, используйте следующий пример:

// file.js function a () { "use strict" ; // строгий режим активирован только для кода внутри функции function nestedFunction () { // и будет также применяться внутри вложенной функции } } Преимущества Продублированные ключи в объекте var zombie = { eyeLeft: 0 , eyeRight: 1 , // … много ключей … eyeLeft: 1 }

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

Переменные без var plane = 5 ;

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

Только представьте переменную i , объявленную глобально. Это может внести беспорядок во все вложенные циклы в приложении.

Продублированные аргументы {}

Обратите внимание что аргумент fromWhom прописан дважды, для данного случая в строгом режиме также будет выводиться ошибка

Чем чревата подобная ошибка:

function run (fromWhom, fromWhom ) {alert(fromWhom)} run(1 , 2 ); // alert: 2 Фиксация arguments внутри функции var run = function (fromWhom ) { arguments = "alien" ; alert(fromWhom); } run("zombie" ); // alert: "alien";

Если использовать строгий режим:

var run = function (fromWhom ) { "use strict" ; arguments = "alien" ; alert(fromWhom); } run("zombie" ); // alert: "zombie";

Насколько неочевидным является то, что при изменении аргументов (arguments = "alien") изменяется именованный аргумент fromWhom ? Директива "use strict" спасёт вас из этого затруднительного положения.

WoollyMittens , пользователь reddit в комментариях предложил:

Вместе со строгим режимом можно установить “linter” (http://www.jshint.com/), что бы избежать глупых ошибок даже до запуска кода. Для большинства редакторов есть соответствующий плагин. Вы можете считать это теми самыми красными волнистыми линиями, которыми подчеркиваются ваши грамматические ошибки, когда вы пишете email, но применительно к коду.

Скоро я поясню как можно это все автоматизировать с помощью grunt.

loz220 , пользователь reddit в

Строгий режим (strict mode) — это особенность спецификации ECMAScript 5, позволяющая переключится в специальную, «ограниченную» версию JavaScript. Строгий режим накладывает ряд ограничений на языковые конструкции, тем самым исключая некоторые подводные камни и предотвращая ошибки. Также в строгом режиме выбрасывается больше исключений, как правило с более подробным описанием ошибки.

Включение strict mode осуществляется при помощи конструкции:

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

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

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

При использовании use strict для всего скрипта нужно быть аккуратным с объединением файлов. При объединении скрипта в strict mode со скриптом в non-strict mode итоговый скрипт будет выполняться в строгом режиме. Это может вызвать некоторые ошибки, которые были не предусмотрены при написании второго скрипта. Поэтому рекомендуется код внутри каждого скрипта оборачивать анонимной функцией и для нее включать строгий режим.

Изменения в строгом режиме

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

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

В строгом режиме в некоторых ситуациях, в которых в обычном режиме просто ничего не происходит, в строгом режиме бросаются исключения. Например, присваивание NaN в обычном режиме ничего не делает, присваивание не происходит, и разработчик не получает какой-либо информации об этом. В строгом режиме такое присваивание генерирует исключение. Аналогично любое другое присваивание, которое в обычном режиме «молча» не выполняется, в строгом режиме вызывает исключение.

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

Аналогично, параметры, передаваемые в функцию, также должны быть уникальны:

Строгий режим запрещает использование конструкции with() {}. Проблема заключается в том, что переменная внутри этого блока может ссылаться как на свойство объекта, переданного в with, так и на локальную переменную или на свойство глобального объекта.

Еще одно отличие строго режима от нестрогого заключается в том, что в строгом режиме при передаче значения this в функцию c помощью call, apply или bind — это значение не оборачивается в объект. В нестрогом режиме, если в качестве this передается строка, число или логическое значение — оно оборачивается в соответствующий объект String, Number или Boolean. Если передается null или undefined — объектом this становится глобальный объект. В строгом режиме значение this передается «как есть»:

Заключение

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

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

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

&& — логическое И

С логическим И на первый взгляд всё просто, если оба операнда истины, то выражение истинно:

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

Но на самом деле всё не так просто. В данном примере мы использовали операторы сравнения, они возвращают логические значения true / false. Но операндами логического И могут быть выражения с арифметическими операторами.

Давайте изменим пример:

В этом примере оператор && вернёт 11. Дело в том, что на самом деле оператор && возвращает последний операнд, если все операнды истинны.

Если хоть один из операндов равен лжи, то && возвратит первый операнд со значением ложь.

В этом примере оператор && вернёт цифру 0. Можно, для более глубокого понимания, усложнить пример.

Что есть ложь в JavaScript

Сейчас хороший повод повторить что есть ложь в JavaScript.

  • Число 0 (ноль).
  • Пустая строка «».
  • Логическое значение false 🙂
  • Значение null.
  • Значение undefined.
  • Значение NaN (Not a Number — не число).

Всё остальное в логическом контексте будет истиной.

|| — логическое ИЛИ

Оператор логического ИЛИ возвращает первое значение true (истина). А если истинных значений нет, то последнее ложное.

Логические выражения вычисляются слево направо. Как только оператор ИЛИ обнаружит значение true — он вернёт его, далее вычеслений не будет. Если не встретит ни одно значение true, то вернёт последнее значение, а оно точно будет false. Мы видим, ИЛИ вычисляет ровно столько значений, сколько необходимо.

! Изучаем JavaScript «use strict». Часть 1

— логическое НЕ

Логическое НЕ — унарный оператор. Он принимает операнд и изменяет его значение истина/ложь на противоположное.

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

Короткий цикл вычислений Оператор || (ИЛИ)

Итак, логические выражения вычисляются слево направо. Например, когда оператор ИЛИ обнаружит значение true — он вернёт его, далее вычеслений не будет. Эту особенность можно использовать для поиска первого истинного выражения в списке.

Переменная result будет равна «Привет!». Постфиксный инкремент myVar++ сработает после вычисления выражения, а префиксный инкремент ++myVar не будет выполнен, так как ранее оператор || обнаружит истину.

Оператор && (И)

Вычисления слево направо, если аргумент - false, оператор && возвращает его и заканчивает вычисления. Иначе - вычисляет дальше, если false в списке нет, возвращает последний правый аргумент, а он будет true.

Вот пример:

Вычисления остановятся на переменной myStr, именно её значение «» и будет присвоено в переменную result.

&& вместо if

В простых случаях можно использовать оператор && вместо инструкции if:

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

The modern mode, «use strict» var (справочник по C#)var (C# Reference)

Начиная с Visual C# 3.0, переменные, объявленные в области действия метода, получают неявный "тип" .Beginning in Visual C# 3.0, variables that are declared at method scope can have an implicit "type" .Неявно типизированные локальные переменные является строго типизированными, как если бы вы объявили тип самостоятельно, однако его определяет компилятор.An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type.Следующие два объявления функционально эквивалентны:The following two declarations of are functionally equivalent:

Дополнительные сведения см. в разделах Неявно типизированные локальные переменные и Связи типов в операциях запроса LINQ.For more information, see Implicitly Typed Local Variables and Type Relationships in LINQ Query Operations.

ПримерExample

В следующем примере показаны два выражения запросов.The following example shows two query expressions.В первом выражении использование разрешено, но не является обязательным, поскольку тип результата запроса может быть задан явно как.In the first expression, the use of is permitted but is not required, because the type of the query result can be stated explicitly as an .Однако во втором выражении благодаря результат может быть коллекцией анонимных типов, и имя этого типа доступно только для компилятора.However, in the second expression, allows the result to be a collection of anonymous types, and the name of that type is not accessible except to the compiler itself.Использование делает создание нового класса для результата необязательным.Use of eliminates the requirement to create a new class for the result.Обратите внимание на то, что во втором примере переменная итерации также типизирована неявно.Note that in Example #2, the iteration variable must also be implicitly typed.

См. такжеSee Also

Справочник по C#C# Reference
Руководство по программированию на C#C# Programming Guide
Неявно типизированные локальные переменныеImplicitly Typed Local Variables

Узнайте, как можно исправить ошибки JavaScript кода с помощью консоли браузера и не только. Будем учиться на примерах, как бороться с js error и другими проблемами. А также поделимся своей практикой борьбы с ошибками в комментариях.

Что мы сегодня узнаем?

Визуализация ошибок в JavaScript

Примеры исправления ошибок с помощью консоли

Как исправить ошибку без консоли

Встречаем консоль!

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

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

Визуализация при исправлении ошибок

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

Консоль браузера, это объект, который может быть использован для вывода информации об ошибках во время загрузки страницы. Для примера: вы можете добраться к любому DOM элементу, например, картинке которая имеет не правильный URL. Для этого нужно навести на элемент (картинку) и нажать правую кнопку мыши. Найти «Проинспектировать элемент » или что-то подобное. В Opera это выглядит так:

Вот мы и в консоле. Почти, остальось выбрать вкладку «консоль».

Консоль, в отличии от «исходного кода», способна видеть текущие изменения на странице, которые вызваны JavaScript кодом.

А вот доступ к консоли в Chrome браузере:

Простые примеры выявления ошибок

Консоль поддерживает множество опций, но можно обойтись 3-4, этого достаточно для выявления и дальнейшего исправления ошибки. Из моего собственного опыта, функция log() , наиболее удобная. Она выводит новые сообщения, DOM элементы, переменные в консоль, где мы можем их видеть. Примеры ниже показывают применение функций, которые я использую.

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

if (full_name != «»){ console.log(‘The name \»‘ + full_name + ‘\» was entered’); }else{ console.error(‘No name was entered’); }

Для события jQuery click, консоль выведет информацию о нажатии элемента (трассировка):

Консоль это больше чем вывод сообщений, она также может принимать команды. Для примера, наберите «document» и нажмите Enter для получения информации о странице.

Как исправить ошибку без консоли?

Если вам сложно разобраться с функциями консоли, или ваш браузер не поддерживает данной функции. Советую воспользоваться простым и проверенным способом для исправления ошибки в коде javascript. По ходу программного кода, можно просто вставлять вывод сообщения alert();

Примеры выявления ошибок с помощью alert

Этот пример позволяет просто вывести значение переменной:

var e= 123; alert(e); // выведет 123

Также можно понять где значение, а где объект:

var e = document.getElementById(id_elementa); alert(e); // выведет сообщение, что выбран объект

Еще одно применение – это определение в какой строке кода произошла ошибка. Для этого вам просто нужно вставить сообщения типа alert(‘Здесь ошибка’); через каждую строку кода. Например:

alert(‘Hello’); var e = document.getElementByIds(‘id_elementa’); alert(‘Hello 2’);

В этом случае выведется только сообщение Hello. Потому-что на второй строке ошибка! Если ошибки не будет, выведутся 2 сообщения.

Строгий режим (strict mode) в JavaScript

Метод тупой, но срабатывает. Главное без использования консоли, скопировал -> вставил и определил где идет ошибка в коде. Если не надо, закомментировал.

Держите страницу в чистоте!

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

Sometimes you"ll see the default, non-strict mode referred to as " " . This isn"t an official term, but be aware of it, just in case.

JavaScript"s strict mode, introduced in ECMAScript 5, is a way to opt in to a restricted variant of JavaScript, thereby implicitly opting-out of " ". Strict mode isn"t just a subset: it intentionally has different semantics from normal code. Browsers not supporting strict mode will run strict mode code with different behavior from browsers that do, so don"t rely on strict mode without feature-testing for support for the relevant aspects of strict mode. Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally.

Strict mode makes several changes to normal JavaScript semantics:

  • Eliminates some JavaScript silent errors by changing them to throw errors.
  • Fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that"s not strict mode.
  • Prohibits some syntax likely to be defined in future versions of ECMAScript.
  • (function() { "use strict"; false.true = ""; // TypeError (14).sailing = "home"; // TypeError "with".you = "far away"; // TypeError })(); Simplifying variable uses

    Strict mode simplifies how variable names map to particular variable definitions in the code. Many compiler optimizations rely on the ability to say that variable X is stored in that location: this is critical to fully optimizing JavaScript code. JavaScript sometimes makes this basic mapping of name to variable definition in the code impossible to perform until runtime. Strict mode removes most cases where this happens, so the compiler can better optimize strict mode code.

    First, strict mode prohibits with . The problem with with is that any name inside the block might map either to a property of the object passed to it, or to a variable in surrounding (or even global) scope, at runtime: it"s impossible to know which beforehand. Strict mode makes with a syntax error, so there"s no chance for a name in a with to refer to an unknown location at runtime:

    "use strict"; var x = 17; with (obj) { // !!! syntax error // If this weren"t strict mode, would this be var x, or // would it instead be obj.x? It"s impossible in general // to say without running the code, so the name can"t be // optimized. x; }

    The simple alternative of assigning the object to a short name variable, then accessing the corresponding property on that variable, stands ready to replace with .

    Second, . In normal code eval("var x;") introduces a variable x into the surrounding function or the global scope. This means that, in general, in a function containing a call to eval every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that eval might have introduced a new variable that would hide the outer variable). In strict mode eval creates variables only for the code being evaluated, so eval can"t affect whether a name refers to an outer variable or some local variable:

    Var x = 17; var evalX = eval(""use strict"; var x = 42; x;"); console.assert(x === 17); console.assert(evalX === 42);

    If the function eval is invoked by an expression of the form eval(...) in strict mode code, the code will be evaluated as strict mode code. The code may explicitly invoke strict mode, but it"s unnecessary to do so.

    Function strict1(str) { "use strict"; return eval(str); // str will be treated as strict mode code } function strict2(f, str) { "use strict"; return f(str); // not eval(...): str is strict if and only // if it invokes strict mode } function nonstrict(str) { return eval(str); // str is strict if and only // if it invokes strict mode } strict1(""Strict mode code!""); strict1(""use strict"; "Strict mode code!""); strict2(eval, ""Non-strict code.""); strict2(eval, ""use strict"; "Strict mode code!""); nonstrict(""Non-strict code.""); nonstrict(""use strict"; "Strict mode code!"");

    Thus names in strict mode eval code behave identically to names in strict mode code not being evaluated as the result of eval .

    Third, strict mode forbids deleting plain names. delete name in strict mode is a syntax error:

    "use strict"; var x; delete x; // !!! syntax error eval("var y; delete y;"); // !!! syntax error

    Making eval and arguments simpler

    Strict mode makes arguments and eval less bizarrely magical. Both involve a considerable amount of magical behavior in normal code: eval to add or remove bindings and to change binding values, and arguments by its indexed properties aliasing named arguments. Strict mode makes great strides toward treating eval and arguments as keywords, although full fixes will not come until a future edition of ECMAScript.

    First, the names eval and arguments can"t be bound or assigned in language syntax. All these attempts to do so are syntax errors:

    "use strict"; eval = 17; arguments++; ++eval; var obj = { set p(arguments) { } }; var eval; try { } catch (arguments) { } function x(eval) { } function arguments() { } var y = function eval() { }; var f = new Function("arguments", ""use strict"; return 17;");

    Second, strict mode code doesn"t alias properties of arguments objects created within it. In normal code within a function whose first argument is arg , setting arg also sets arguments , and vice versa (unless no arguments were provided or arguments is deleted). arguments objects for strict mode functions store the original arguments when the function was invoked. arguments[i] does not track the value of the corresponding named argument, nor does a named argument track the value in the corresponding arguments[i] .

    Function f(a) { "use strict"; a = 42; return ; } var pair = f(17); console.assert(pair === 42); console.assert(pair === 17);

    Third, arguments.callee is no longer supported. In normal code arguments.callee refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. arguments.callee for strict mode functions is a non-deletable property which throws an error when set or retrieved:

    "use strict"; var f = function() { return arguments.callee; }; f(); // throws a TypeError

    "Securing" JavaScript

    Strict mode makes it easier to write "secure" JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website on behalf of other users . JavaScript in browsers can access the user"s private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript"s flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has a considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.

    First, the value passed as this to a function in strict mode is not forced into being an object (a.k.a. "boxed"). For a normal function, this is always an object: either the provided object if called with an object-valued this ; the value, boxed, if called with a Boolean, string, or number this ; or the global object if called with an undefined or null this . (Use call , apply , or bind to specify a particular this .) Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard because the global object provides access to functionality that "secure" JavaScript environments must restrict. Thus for a strict mode function, the specified this is not boxed into an object, and if unspecified, this will be undefined:

    "use strict"; function fun() { return this; } console.assert(fun() === undefined); console.assert(fun.call(2) === 2); console.assert(fun.apply(null) === null); console.assert(fun.call(undefined) === undefined); console.assert(fun.bind(true)() === true);

    That means, among other things, that in browsers it"s no longer possible to reference the window object through this inside a strict mode function.

    Second, in strict mode it"s no longer possible to "walk" the JavaScript stack via commonly-implemented extensions to ECMAScript. In normal code with these extensions, when a function fun is in the middle of being called, fun.caller is the function that most recently called fun , and fun.arguments is the arguments for that invocation of fun . Both extensions are problematic for "secure" JavaScript because they allow "secured" code to access "privileged" functions and their (potentially unsecured) arguments. If fun is in strict mode, both fun.caller and fun.arguments are non-deletable properties which throw when set or retrieved:

    Function restricted() { "use strict"; restricted.caller; // throws a TypeError restricted.arguments; // throws a TypeError } function privilegedInvoker() { return restricted(); } privilegedInvoker();

    Third, arguments for strict mode functions no longer provide access to the corresponding function call"s variables. In some old ECMAScript implementations arguments.caller was an object whose properties aliased variables in that function. This is a security hazard because it breaks the ability to hide privileged values via function abstraction; it also precludes most optimizations. For these reasons no recent browsers implement it. Yet because of its historical functionality, arguments.caller for a strict mode function is also a non-deletable property which throws when set or retrieved:

    "use strict"; function fun(a, b) { "use strict"; var v = 12; return arguments.caller; // throws a TypeError } fun(1, 2); // doesn"t expose v (or a or b)

    Paving the way for future ECMAScript versions

    Future ECMAScript versions will likely introduce new syntax, and strict mode in ECMAScript 5 applies some restrictions to ease the transition. It will be easier to make some changes if the foundations of those changes are prohibited in strict mode.

    First, in strict mode, a short list of identifiers become reserved keywords. These words are implements , interface , let , package , private , protected , public , static , and yield . In strict mode, then, you can"t name or use variables or arguments with these names.

    Function package(protected) { // !!! "use strict"; var implements; // !!! interface: // !!! while (true) { break interface; // !!! } function private() { } // !!! } function fun(static) { "use strict"; } // !!!

    Two Mozilla-specific caveats: First, if your code is JavaScript 1.7 or greater (for example in chrome code or when using the right ) and is strict mode code, let and yield have the functionality they"ve had since those keywords were first introduced. But strict mode code on the web, loaded with or ... , won"t be able to use let / yield as identifiers. Second, while ES5 unconditionally reserves the words class , enum , export , extends , import , and super , before Firefox 5 Mozilla reserved them only in strict mode.

    Second, . In normal mode in browsers, function statements are permitted "everywhere". This is not part of ES5 (or even ES3)! It"s an extension with incompatible semantics in different browsers. Note that function statements outside top level are permitted in ES2015.

    "use strict"; if (true) { function f() { } // !!! syntax error f(); } for (var i = 0; i < 5; i++) { function f2() { } // !!! syntax error f2(); } function baz() { // kosher function eit() { } // also kosher }

    This prohibition isn"t strict mode proper because such function statements are an extension of basic ES5. But it is the recommendation of the ECMAScript committee, and browsers will implement it.

    Strict mode in browsers

    The major browsers now implement strict mode. However, don"t blindly depend on it since there still are numerous Browser versions used in the wild that only have partial support for strict mode or do not support it at all (e.g. Internet Explorer below version 10!). Strict mode changes semantics. Relying on those changes will cause mistakes and errors in browsers which don"t implement strict mode. Exercise caution in using strict mode, and back up reliance on strict mode with feature tests that check whether relevant parts of strict mode are implemented. Finally, make sure to test your code in browsers that do and don"t support strict mode . If you test only in browsers that don"t support strict mode, you"re very likely to have problems in browsers that do, and vice versa.

    Specifications Specification Status Comment
    ECMAScript 5.1 (ECMA-262)
    Standard Initial definition. See also:
    ECMAScript 2015 (6th Edition, ECMA-262)
    The definition of "Strict Mode Code" in that specification.
    Standard Strict mode restriction and exceptions
    ECMAScript Latest Draft (ECMA-262)
    The definition of "Strict Mode Code" in that specification.
    Draft
    Понравилось? Лайкни нас на Facebook