Javascript with strict mode

Строгий режим — «use strict»

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

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

Так было до 2009 года, когда появился ECMAScript 5 (ES5). Он добавил новые возможности в язык и изменил некоторые из существующих. Чтобы устаревший код работал, как и раньше, по умолчанию подобные изменения не применяются. Поэтому нам нужно явно их активировать с помощью специальной директивы: «use strict» .

«use strict»

Директива выглядит как строка: «use strict» или ‘use strict’ . Когда она находится в начале скрипта, весь сценарий работает в «современном» режиме.

"use strict"; // этот код работает в современном режиме . 

Позже мы изучим функции (способ группировки команд). Забегая вперёд, заметим, что вместо всего скрипта «use strict» можно поставить в начале большинства видов функций. Это позволяет включить строгий режим только в конкретной функции. Но обычно люди используют его для всего файла.

Проверьте, что «use strict» находится в первой исполняемой строке скрипта, иначе строгий режим может не включиться.

Здесь строгий режим не включён:

alert("some code"); // "use strict" ниже игнорируется - он должен быть в первой строке "use strict"; // строгий режим не активирован

Над «use strict» могут быть записаны только комментарии.

Нет директивы типа «no use strict» , которая возвращала бы движок к старому поведению.

Как только мы входим в строгий режим, отменить это невозможно.

Консоль браузера

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

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

Итак, как можно включить use strict в консоли?

Можно использовать Shift + Enter для ввода нескольких строк и написать в верхней строке use strict :

В большинстве браузеров, включая Chrome и Firefox, это работает.

Читайте также:  PHP: Get Values of Multiple Checked Checkboxes

Если этого не происходит, например, в старом браузере, есть некрасивый, но надежный способ обеспечить use strict . Поместите его в следующую обёртку:

Всегда ли нужно использовать «use strict»?

Вопрос кажется риторическим, но это не так.

Кто-то посоветует начинать каждый скрипт с «use strict» … Но есть способ покруче.

Современный JavaScript поддерживает «классы» и «модули» — продвинутые структуры языка (и мы, конечно, до них доберёмся), которые автоматически включают строгий режим. Поэтому в них нет нужды добавлять директиву «use strict» .

Подытожим: пока очень желательно добавлять «use strict»; в начале ваших скриптов. Позже, когда весь ваш код будет состоять из классов и модулей, директиву можно будет опускать.

Пока мы узнали о use strict только в общих чертах.

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

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

Источник

JavaScript Strict Mode

В пятой редакции ECMAScript был представлен строгий режим (далее в статье 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 будут использовать его.

Читайте также:  Php my admin уязвимости

Какие правила включены в 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 репозитории. Я уверен, что там есть пара ошибок — не стесняйтесь присылать ошибки!

Читайте также:  Функция abs python примеры

От переводчика: тут в статье шел огромный кусок кода, закинул его на 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). Сейчас самое время начать эксперименты!

Источник

Оцените статью