Use strict что это
Use strict, что это? Зачем в JavaScript нужен строгий режим?
Use strict JavaScript — это модель разработки, которая часто используется в современном программировании на JavaScript. Главная особенность этого режима, что он дает возможность разработчикам использовать только ограниченный синтаксис и не допускать лишних ошибок.
Синтаксис «строгого режима» отличается от традиционного синтаксиса JavaScript. В нем не проходят многие ошибки, которые легко пройдут в стандартном. Поэтому очень часто стандартный синтаксис называют «грязным», от того что в нем многие мелкие ошибки игнорируются. Такое «игнорирование» — это не всегда плохо. В мелких проектах молодых разработчиков оно ни к чему плохому не приводит. Но если проект большой, то наличие в коде «мелких» ошибок иногда может привести к непредсказуемым результатам. И чтобы этого не произошло, разработчики применяют режим use strict при разработке на языке JavaScript.
Строгий режим не даст системе закрыть глаза на «тихие» ошибки и заставит ее остановить процесс выполнения программы в случае их обнаружения. То есть этот режим дает возможность писать программы, в которых не будет недочетов.
Use strict в JavaScript
Use strict в JavaScript может применяться ко всему документу сразу или к отдельным его функциям. Для того чтобы включить этот режим в документе, необходимо в нужном месте разместить выражение «Use strict» в одинарных или двойных кавычках.
Когда нет желания подключать весь документ к строгому режиму, нужно осторожно относит ь ся к чередованию «строгих» или «нестрогих» функций в документе. Иногда в такой смеси под «строгий режим» попадает код функции, которая для этого не рассчитана. И наоборот, код, который должен быть в «строгом» режиме, попадает под «нестрогий».
Отличия «use strict» и стандартный режим в JavaScript
Применение « U se strict» вносит следующие изменения в JavaScript:
При режиме «strict» к неопределенной переменной не присваивается значение.
Нельзя применить инструкцию «with».
Нет возможности добавить повторяющиеся свойства в литерале объекта.
Нет возможности добавить дополнительные параметры формальной функции.
Когда изменяется объект «arguments», не изменяются аргументы.
Когда аргумент является неизменяемым свойством объекта, то «delete» выдаст ошибку.
Нет возможности преобразовать «this» в объект.
Нет возможности изменять «eval» и «arguments», а также применять их в качестве имени.
Увеличенное количество слов, которые зарезервировали для будущего применения.
Нет возможности использовать восьмеричную систему.
Нет возможности применять конструкции кода, которые могут затруднить оптимизацию самого кода.
Нельзя объявить переменную в коде, который был передан методу «eval».
Нельзя удалить обычные переменные.
Заключение
Use strict в JavaScript — это то, что делает код чище и безопасней. Этот режим существует уже очень долго и поддерживается всеми современными браузерами. Проблемы с этим режимом могут возникнуть только в старых версиях Internet Explorer.
Use strict в JavaScript часто используется для лучшей оптимизации программы, а также для поиска «тихих» ошибок, которые могут давать неоднозначные результаты.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Строгий режим Javascript
Директива «use strict»; указывает, что код JavaScript должен выполняться в «строгом режиме».
Директива «use strict» была добавлена в JavaScript 1.8.5 (ECMAScript версии 5).
Это не оператор, а константное выражение, которое игнорируется более ранними версиями JavaScript.
Цель директивы «use strict» — указать, что код должен выполняться в, так называемом, «строгом режиме».
В строгом режиме вы не можете, например, использовать не декларированные переменные.
Строгий режим поддерживается в:
Декларирование строгого режима
Строгий режим декларируется путем добавления директивы «use strict»; в начало скрипта или функции.
Если директива указана в начале скрипта, то она имеет глобальный эффект (весь код скрипта выполняется в строгом режиме):
Если директива указана внутри функции, то она имеет локальный эффект (только код внутри функции выполняется в строгом режиме):
Синтаксис директивы «use strict»;
Синтаксис директивы, декларирующей строгий режим, разработан таким образом, чтобы была совместимость со старыми версиями JavaScript.
Компилирование числовых (4 + 5;) или строковых («John Doe»;) констант в программе JavaScript не имеет побочных эффектов. Они просто компилируются в несуществующую переменную и умирают.
Таким образом, строковая константа «use strict»; срабатывает только в новых компиляторах, которые «понимают» ее значение.
Зачем нужен строгий режим?
Благодаря строгому режиму проще писать «безопасный» JavaScript код.
В строгом режиме ранее вполне приемлемый «плохой синтаксис» превращается в реальные ошибки.
К примеру, в обычном режиме JavaScript опечатка в имени переменной приводит к созданию новой глобальной переменной. В строгом режиме это приведет к ошибке, что защищает от случайного создания глобальных переменных.
В обычном режиме JavaScript разработчик не получит никакого сообщения об ошибке, если попытается присвоить какое-либо значение свойствам, не предназначенным для записи.
В строгом режиме любая попытка присвоить какое-либо значение не предназначенному для записи свойству, свойству, определенному, как только для чтения, несуществующей переменной или несуществующему объекту приведет к возникновению ошибки.
Ограничения в строгом режиме
Нельзя использовать переменные без декларирования:
Внимание! Объекты тоже переменные.
Нельзя использовать объекты без декларирования:
Нельзя удалять переменную (или объект):
Нельзя удалять функцию:
Одинаковые имена параметров запрещены:
Восьмеричные числовые константы запрещены:
Восьмеричные экранированные символы запрещены:
Запись в свойства, предназначенные только для чтения, запрещено:
Запись в свойства, предназначенные только для возврата значения, запрещено:
Нельзя удалять неудаляемые свойства:
Нельзя использовать строку «eval» в качестве имени переменной:
Нельзя использовать строку «arguments» в качестве имени переменной:
Нельзя использовать выражение with:
По соображениям безопасности, функции eval() запрещено создавать переменные в области видимости, где она была вызвана:
В вызовах функций как f(), значением this был глобальный объект. В строгом режиме оно undefined.
Задел на будущее
В строгом режиме нельзя использовать будущие зарезервированные слова. Это implements, interface, let, package, private, protected, public, static, yield.
ВНИМАНИЕ!
Директива «use strict» распознается только в начале скрипта или функции.
Строгий режим — «use strict»
На протяжении долгого времени JavaScript развивался без проблем с обратной совместимостью. Новые функции добавлялись в язык, в то время как старая функциональность не менялась.
Преимуществом данного подхода было то, что существующий код продолжал работать. А недостатком – что любая ошибка или несовершенное решение, принятое создателями JavaScript, застревали в языке навсегда.
«use strict»
Позже мы изучим функции (способ группировки команд). Забегая вперёд, заметим, что вместо всего скрипта «use strict» можно поставить в начале большинства видов функций. Это позволяет включить строгий режим только в конкретной функции. Но обычно люди используют его для всего файла.
Проверьте, что «use strict» находится в первой исполняемой строке скрипта, иначе строгий режим может не включиться.
Здесь строгий режим не включён:
Над «use strict» могут быть записаны только комментарии.
Как только мы входим в строгий режим, отменить это невозможно.
Консоль браузера
В дальнейшем, когда вы будете использовать консоль браузера для тестирования функций, обратите внимание, что use strict по умолчанию в ней выключен.
Иногда, когда use strict имеет значение, вы можете получить неправильные результаты.
Можно использовать Shift + Enter для ввода нескольких строк и написать в верхней строке use strict :
В большинстве браузеров, включая Chrome и Firefox, это работает.
Всегда ли нужно использовать «use strict»?
Вопрос кажется риторическим, но это не так.
Кто-то посоветует начинать каждый скрипт с «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 будет применен для всего кода:
В качестве альтернативы вы можете включить Strict Mode только в отдельной функции, добавив «use strict» в начало тела вашей функции:
Наследуют ли внутренние функции Strict Mode от внешних функций?
Внутренняя функция, объявленная внутри внешней, в которой включен Strict Mode тоже будет иметь Strict Mode:
Важно запомнить, что Strict Mode не распространяется на «нестрогие» (ориг. non-strict) функции, которые выполняются внутри строгой функции (или они отправлены в функцию в качестве аргументов или выполняются, используя call или apply):
Почему я не могу включить Strict Mode в консоли моего браузера?
Когда выполняешь код в консоли фаербага или в других консолях использование «use strict» вне функции не имеет силы. Это потому, что большинство консолей обрамляют ваш код в eval’ом, поэтому ваш «use strict» не является первым выражением. Это можно обойти, обрамив ваш код в замыкание (IIFE), в начало которого мы положим «use strict» (но, когда я тестировал такой способ включения Strict Mode я понял, что это довольно неудобно, особенно если работать в консоли webkit developer tools — лучше тестировать ваш код на странице):
Что произойдет если мой браузер не поддерживает 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). Сейчас самое время начать эксперименты!
Переход к строгому режиму
Цель этой статьи: предоставить для разработчиков руководство по переходу к строгому режиму.
Постепенный переход
Строгий режим был спроектирован таким образом, чтобы переход к нему можно было сделать постепенно. Каждый файл можно переводить к строгому режиму поодиночке, и даже есть возможность включить строгий режим для каждой функции по отдельности.
Различия non-strict и strict режимов
Синтаксические ошибки
При добавлении «use strict»; следующие случаи вызывают SyntaxError до выполнения скрипта:
Эти ошибки хороши тем, что обличают скользкие, едва уловимые ошибки и плохие практики написания кода.
Новые ошибки времени выполнения (runtime errors)
Ранее JavaScript не показывал никаких ошибок и предупреждений в некоторых случаях выполнения некорректного кода. Строгий режим выбрасывает исключения в таких случаях. Если в вашем коде есть такие случаи, тестирование будет необходимо, чтобы убедиться, что ничего не сломалось после перехода к строгому режиму. Ещё раз это может случится на уровне детализации функции.
Установка значения необъявленной переменной
Здесь изменяется значение глобального объекта, что редко является ожидаемым эффектом. Если вы действительно хотите изменить значение глобального объекта, передайте его в качестве аргумента функции и явно присвойте его как свойство:
Попытка удалить неконфигурируемое свойство
В нестрогом режиме этот код может молчаливо выполниться неудачей и ничего не сделать, вопреки ожиданиям.
Отравленные аргументы (arguments) и свойства функции
может быть переписан как:
Семантические различия
Эти различия очень тонкие. Вполне возможно, что тесты не поймают этот тип едва уловимых отличий. Вероятно, потребуется тщательная рецензия кода, чтобы удостовериться, что эти различия не влияют на семантику вашего кода. К счастью, этот анализ может быть сделан постепенно, спускаясь вниз к реализации каждой конкретной функции.
this в вызовах функции
arguments не является псевдонимом именованных аргументов функции
В нестрогом режиме изменение значения в объекте arguments изменяло соответствующий именованный аргумент функции. Это усложняло оптимизацию кода для движков JavaScript и сам код становился менее читабельным и понятным. В строгом режиме объект arguments создаётся и инициализируется с теми же значениями, что и именованные аргументы, но изменения объекта arguments или именованных аргументов теперь никак не влияют друг на друга.
Изменения в eval
В строгом режиме eval не создаёт новой переменной в той области видимости, где был вызван. Также, конечно, в строгом режиме, строка выполняется с правилами строгого режима. Потребуется провести тщательное тестирование, чтобы убедиться, что ничего не сломалось. Не использовать eval, если он вам действительно не нужен, может быть другим прагматичным решением.