Строгий режим — "use strict"
На протяжении долгого времени JavaScript развивался без проблем с обратной совместимостью. Новые функции добавлялись в язык, в то время как старая функциональность не менялась.
Преимуществом данного подхода было то, что существующий код продолжал работать. А недостатком – что любая ошибка или несовершенное решение, принятое создателями JavaScript, застревали в языке навсегда.
Так было до 2009 года, когда появился ECMAScript 5 (ES5). Он добавил новые возможности в язык и изменил некоторые из существующих. Чтобы устаревший код работал, как и раньше, по умолчанию подобные изменения не применяются. Поэтому нам нужно явно их активировать с помощью специальной директивы: "use strict" .
«use strict»
Директива выглядит как строка: "use strict" или ‘use strict’ . Когда она находится в начале скрипта, весь сценарий работает в «современном» режиме.
Позже мы изучим функции (способ группировки команд). Забегая вперёд, заметим, что вместо всего скрипта "use strict" можно поставить в начале большинства видов функций. Это позволяет включить строгий режим только в конкретной функции. Но обычно люди используют его для всего файла.
Проверьте, что "use strict" находится в первой исполняемой строке скрипта, иначе строгий режим может не включиться.
Здесь строгий режим не включён:
Над "use strict" могут быть записаны только комментарии.
Нет директивы типа "no use strict" , которая возвращала бы движок к старому поведению.
Как только мы входим в строгий режим, отменить это невозможно.
Консоль браузера
В дальнейшем, когда вы будете использовать консоль браузера для тестирования функций, обратите внимание, что use strict по умолчанию в ней выключен.
Иногда, когда use strict имеет значение, вы можете получить неправильные результаты.
Итак, как можно включить use strict в консоли?
Можно использовать Shift + Enter для ввода нескольких строк и написать в верхней строке use strict :
В большинстве браузеров, включая Chrome и Firefox, это работает.
Если этого не происходит, например, в старом браузере, есть некрасивый, но надежный способ обеспечить use strict . Поместите его в следующую обёртку:
Всегда ли нужно использовать «use strict»?
Вопрос кажется риторическим, но это не так.
Кто-то посоветует начинать каждый скрипт с "use strict" … Но есть способ покруче.
Современный JavaScript поддерживает «классы» и «модули» — продвинутые структуры языка (и мы, конечно, до них доберёмся), которые автоматически включают строгий режим. Поэтому в них нет нужды добавлять директиву "use strict" .
Подытожим: пока очень желательно добавлять "use strict"; в начале ваших скриптов. Позже, когда весь ваш код будет состоять из классов и модулей, директиву можно будет опускать.
Пока мы узнали о use strict только в общих чертах.
В следующих главах, по мере расширения знаний о возможностях языка, мы яснее увидим отличия между строгим и стандартным режимом. К счастью, их не так много, и все они делают жизнь разработчика лучше.
Все примеры в этом учебнике подразумевают исполнение в строгом режиме, за исключением случаев (очень редких), когда оговорено иное.
Зачем нужен Strict Mode в JavaScript?
![]()
Строгий режим — это важная часть современного JavaScript. Он позволяет использовать ограниченный синтаксис JavaScript.
Семантика строгого режима отличается от старого “неаккуратного режима” JavaScript с его слабым синтаксисом и “замалчиваемыми” ошибками в коде — такие ошибки игнорируются, и код может запускаться с неожиданными результатами.
Строгий режим вносит несколько изменений в семантику JavaScript. Он заменяет исключениями “замалчиваемые” в обычном режиме ошибки, поэтому с этими ошибками код не запускается.
Он также исправляет ошибки, мешающие движкам JavaScript производить оптимизацию, и запрещает функции, которые могут быть определены в будущих версиях JavaScript.
Строгий режим применим как к отдельным функциям, так и к целому скрипту. Его нельзя применять только к операторам и другим блокам, заключенным в фигурные скобки. Чтобы скрипт использовал строгий режим, добавляем оператор "use strict" или 'use strict' в начало скрипта перед всеми остальными операторами.
Будьте внимательны: при объединении со скриптами, использующими строгий режим, скрипты, которые его не используют, начинают его использовать, и наоборот, поэтому объединять скрипты с разными режимами не стоит.
Чтобы применить строгий режим к функциям, нужно добавить оператор "use strict" или 'use strict' внутрь функции перед всеми остальными операторами. Он применяется ко всему, что находится внутри, включая вложенные функции.
В модулях JavaScript, представленных в ES2015, строгий режим применяется автоматически, поэтому его не нужно включать операторами.
Изменения в строгом режиме
Строгий режим изменяет и синтаксис, и поведение кода во время выполнения. Наиболее важные изменения:
- преобразование ранее допустимых ошибок в ошибки синтаксиса или ошибки выполнения;
- изменения, упрощающие вычисление конкретных переменных;
- изменения, упрощающие функцию eval и объект arguments ;
- изменения, которые будут применены в будущей спецификации ES.
Преобразование допустимых ошибок в недопустимые
В нестрогом режиме на некоторые допустимые ошибки JS никак не реагировал. Строгий режим ограничивает использование ошибочного синтаксиса и не позволяет коду запускаться с ошибками.
Он затрудняет создание глобальных переменных, не позволяя объявлять переменные с помощью var , let или const . Например, код ниже выдаст ReferenceError :
Код не запустится в строгом режиме — глобальную переменную badVariable можно создать только при выключенном строгом режиме, который нужен для предотвращения случайного создания глобальных переменных.
Теперь любой код с этой ранее допустимой ошибкой выдаст исключение. Это распространяется и на некорректный синтаксис, который игнорировался ранее.
Например, в строгом режиме мы не можем присваивать значения переменным только для чтения: arguments , NaN или eval . Любое присвоение значений защищенным от записи глобальным переменным, свойствам только для геттеров и свойствам нерасширяемых объектов в строгом режиме выдаст исключение.
Ниже несколько примеров неудачного синтаксиса:
Все примеры выше выдадут TypeError . undefined и Infinity — глобальные переменные, защищенные от записи, obj — защищенное от записи свойство.
Свойство foo obj2 — единственное свойство геттера, и поэтому не может быть задано. fixedObj был защищен от добавления новых свойств методом Object.preventExtensions .
Кроме того, при попытке удалить неудаляемые свойства появится исключение TypeError , например:
В строгом режиме имена параметров функции должны быть уникальны. В обычном режиме, если у двух параметров одинаковое имя, определенное позже имя будет принято как значение параметра при передаче аргументов. Поэтому следующий пример выдаст синтаксическую ошибку:
В строгом режиме восьмеричная запись чисел также не разрешена. Она не является частью спецификации, но поддерживается в браузерах добавлением 0 к восьмеричным числам. Это сбивает разработчиков с толку, так как некоторые думают, что 0 перед числом ничего не значит. Как следствие, строгий режим не разрешает этот синтаксис и выдает ошибку.
Строгий режим предотвращает использование синтаксиса, усложняющего оптимизацию. Ему нужно знать, что переменная действительно хранится в том месте, где он думает, до того, как производить оптимизацию.
Один из примеров — это оператор with . При его использовании интерпретатор JavaScript не знает, на какую переменную или свойство вы ссылаетесь, поскольку переменная с тем же именем может быть внутри или снаружи оператора with .
JavaScript не будет знать, x внутри оператора with ссылается на переменную x или свойство obj , obj.x .
Следовательно, расположение x в памяти неоднозначно. Таким образом, строгий режим запрещает использование оператора with . При включенном строгом режиме пример ниже выдаст ошибку:
Следующая вещь, запрещенная в строгом режиме — это объявление переменных внутри оператора eval .
Например, без строгого режима eval('let x') объявит переменную x внутри кода. Это позволяет программистам прятать объявление переменных в строках, что может блокировать объявление той же переменной вне оператора eval .
Чтобы предотвратить это, строгий режим не позволяет объявлять переменные в аргументе строки, который мы передаем внутрь оператора eval .
Строгий режим также запрещает удаление простых имен переменных, поэтому код ниже выдаст синтаксическую ошибку:
Запрет неверного синтаксиса
Неверный синтаксис метода eval и объекта argument не разрешен в строгом режиме.
Например, им нельзя задать новые значения или использовать их как имена переменных, функций или параметров функций.
Вот пример неверного использования eval и argument :
Строгий режим не разрешает создавать псевдоним для объекта arguments и задавать с ним новые значения.
Без строгого режима, если первый параметр функции — a , тогда установка a также задает arguments[0] . В строгом режиме у объекта arguments всегда будет список аргументов, с которыми вызывается функция.
Например, если у нас есть:
Тогда мы должны увидеть [2,1] в журнале, потому что установка значения 2 в a не задает его в arguments[0] .
Оптимизация производительности
Кроме того, больше нет поддержки arguments.callee . Без строгого режима arguments.callee возвращает имя функции с arguments.callee внутри.
Это мешает оптимизациям, например, встроенным функциям, потому что arguments.callee требует, чтобы при его вызове была доступна ссылка на невстроенную функцию. Поэтому теперь в строгом режиме arguments.callee вызывает TypeError .
В строгом режиме значение this не приводится к объекту. Если this функции связан с call , apply или bind с любыми необъектными типами, такими как примитивные типы undefined , null , number , boolean и так далее, они будут принудительно приведены к объекту.
Если контекст this переключается в необъектный режим, его место занимает глобальный объект window . Это означает, что глобальный объект открыт для функции, вызываемой this , связанным с необъектным типом.
Например, если мы запустим код ниже:
Все журналы консоли будут иметь значение true , так как this внутри функции не преобразуется автоматически в глобальный объект window , когда this меняется на что-то, имеющее необъектный тип.
Исправления безопасности
В строгом режиме caller и arguments не публичные, так как caller может отображать функцию, вызывающую другую функцию, к которой обращается это свойство caller .
В arguments есть аргументы, передаваемые при вызове функции. Например, если у нас есть функция fn , тогда через fn.caller мы можем увидеть аргументы, которые были переданы в fn , когда был совершен ее вызов.
Это создает потенциальную дыру в безопасности, которая устраняется запретом доступа к этим двум свойствам функции.
В строгом режиме в примере выше мы не сможем получить доступ к secretFunction.caller и secretFunction.arguments , так как люди могут использовать их для получения стека функций. При выполнении код выдаст TypeError .
Идентификаторы, которые станут ключевыми словами в будущих версиях JavaScript, нельзя использовать для именования переменных или свойств объектов. В ES2015 или позже следующие ключевые слова стали зарезервированными, и их нельзя использовать для определения идентификаторов в коде: implements , interface , let , package , private , protected , public , static и yield .
Строгий режим был стандартом несколько лет. Обычно браузеры его поддерживают. Проблемы могут возникнуть только в старых браузерах, таких как Internet Explorer.
У других браузеров не должно быть проблем в работе со строгим режимом, поэтому его стоит использовать для предотвращения перечисленных выше ошибок.
JavaScript Строгий режим — ‘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 имеет значение, вы можете получить неправильные результаты.
Можно использовать Shift + Enter для ввода нескольких строк и написать в верхней строке use strict :
В большинстве браузеров, включая Chrome и Firefox, это работает.
В старых браузерах консоль не учитывает такой use strict , там можно «оборачивать» код в функцию, вот так:
Всегда ли нужно использовать «use strict»?
Вопрос кажется риторическим, но это не так.
Кто-то посоветует начинать каждый скрипт с ‘use strict’ … Но есть способ покруче.
Современный JavaScript поддерживает «классы» и «модули» — продвинутые структуры языка (и мы, конечно, до них доберёмся), которые автоматически включают строгий режим. Поэтому в них нет нужды добавлять директиву ‘use strict’ .
Подытожим: пока очень желательно добавлять ‘use strict’ ; в начале ваших скриптов. Позже, когда весь ваш код будет состоять из классов и модулей, директиву можно будет опускать.
Пока мы узнали о use strict только в общих чертах.
В следующих главах, по мере расширения знаний о возможностях языка, мы яснее увидим отличия между строгим и стандартным режимом. К счастью, их не так много, и все они делают жизнь разработчика лучше.
Все примеры в этом учебнике подразумевают исполнение в строгом режиме, за исключением случаев (очень редких), когда оговорено иное.
Как работает режим strict в JavaScript
JavaScript — универсальный и широко используемый язык программирования для веб-разработки. Однако его гибкость иногда может привести к непредвиденным последствиям, поэтому разработчикам крайне важно писать надежный и удобный для сопровождения код.
Один из способов добиться этого — использовать «строгий режим» JavaScript или режим Strict.
В этой статье мы подробно рассмотрим режим strict на JavaScript, обсудим, что это такое, как он работает и как он может помочь вам писать лучший код.
Что такое режим Strict
Строгий режим или Strict — это функция, представленная в ECMAScript 5 (ES5), которая позволяет разработчикам использовать более строгий и безопасный вариант JavaScript.
При активации он применяет строгие правила и ограничения, помогая выявлять распространенные ошибки и повышать качество кода. Строгий режим можно включить для каждого файла или функции, что позволяет разработчикам выбирать, где применять его ограничения.
Зачем использовать строгий режим
- Предотвращение ошибок. Строгий режим помогает предотвратить потенциальные ошибки, которые в обычном режиме просто игнорировались бы.
- Упрощенная отладка. Благодаря раннему обнаружению ошибок строгий режим может ускорить и повысить эффективность отладки.
- Улучшенная производительность. Некоторые оптимизации возможны только в строгом режиме, поскольку он устраняет некоторые подверженные ошибкам функции языка.
- Забота о будущем. Строгий режим запрещает использование устаревших функций или функций, которые скоро станут устаревшими, помогая вашему коду оставаться совместимым с будущими версиями JavaScript.
Как включить строгий режим
Включение строгого режима выполняется прямо в коде. Просто добавьте следующее в начало файла JavaScript:
Эта директива информирует интерпретатор JavaScript о необходимости применения правил Strict для всего файла или функции, в которой он появляется.
Имейте в виду, что включение строгого режима в одном скрипте или функции не влияет на другие скрипты или функции.
Использование строгого режима в Node
Node также поддерживает строгий режим. У вас есть 2 варианта с этим подходом.
Первый вариант — использовать «use strict»; в начале файлов, которые вы обрабатываете в Node.
Второй — загрузить узел через cli в строгом режиме:
Главное, что следует помнить — вы загружаете всё приложение в строгом режиме. Режим затронет любые сторонние библиотеки, которые вы используете.
Если сторонняя программа плохо работает в строгом режиме, вас оповестят об этом, и, возможно, вам не следует использовать Strict.
Ограничения Strict-режима
Строгий режим применяет несколько правил и ограничений, которые помогают улучшить качество кода. Вот некоторые из наиболее значительных обграничений.
Объявление переменной
В строгом режиме вы должны объявить переменные с помощью ключевых слов var, let или const перед их использованием. В противном случае возникнет ошибка.
Это предотвратит случайное создание глобальной переменной.
Повторяющиеся имена параметров
Строгий режим запрещает функции с повторяющимися именами параметров. При попытке использовать их возникнет синтаксическая ошибка.
Восьмеричные литералы
Восьмеричные литералы (например, 0123) не допускаются в строгом режиме, и попытка их использования приведет к синтаксической ошибке. Вместо этого используйте префикс 0o для восьмеричных чисел.
Назначение свойств только для чтения
В строгом режиме попытка присвоить значение свойству, доступному только для чтения (например, глобальной переменной, такой как undefined , или свойству только для чтения встроенного объекта) приведет к ошибке TypeError .
Оператор with
Оператор with запрещен в строгом режиме, так как он может привести к неоднозначному и трудно отлаживаемому коду.
Использование with в строгом режиме приведет к синтаксической ошибке.
Изменения eval
В строгом режиме eval имеет собственную область видимости, и переменные, объявленные внутри вызова eval , не попадают в окружающую область.
Кроме того, присвоение eval или использование его в качестве имени функции запрещено.
Значение this
В нестрогом режиме значение this внутри функции, вызываемой без явного получателя (например, в качестве отдельной функции, а не метода), по умолчанию равно глобальному объекту.
В строгом режиме this является undefined , что помогает предотвратить случайные изменения глобального объекта.
Строгий режим JavaScript — это мощный инструмент, который может помочь вам написать более надежный, удобный в сопровождении и ориентированный на будущее код.
Применяя более строгие правила и ограничения, строгий режим помогает выявлять распространенные ошибки кодирования, повышать производительность и обеспечивать совместимость с будущими версиями JavaScript.
Поняв и приняв строгий режим, вы сможете улучшить свои навыки разработки JavaScript и создавать более качественные веб-приложения.