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

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

Создание строгого режима

Чтобы включить строгий режим в вашем скрипте, вам просто нужно добавить «use strict» в самой первой строке вашего скрипта.

С другой стороны, строгий режим и небрежный режим могут сосуществовать. Вы можете использовать оба в одном файле.

Чтобы использовать как строгий, так и неряшливый режимы, вам нужно написать код, который вы хотите, в строгом режиме после «использовать строгий», а остальной код — перед «использовать строгий».

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

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

Пример параметров по умолчанию

Пример остальных параметров

Пример деструктурированных параметров

Автоматический строгий режим

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

Строгий режим автоматически применяется в:

Классы

Во всех частях класса автоматически включается строгий режим.

Модули

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

JSON (нотация объектов JavaScript)

JSON — это формат данных, часто используемый для передачи данных между серверами и веб-приложениями. Он всегда работает в строгом режиме и отключить его нельзя.

Что именно делает строгий режим?

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

Необъявленные переменные

В строгом режиме вы не можете повторно объявить переменную без использования var, let или const. Эта функция не позволяет нам создавать глобальные переменные.

Если вы не знакомы с переменными, рекомендую вам о них прочитать.

Назначение свойств объекта

Есть 3 ситуации, когда вы не можете назначить свойство в строгом режиме.

Свойство, недоступное для записи

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

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

Однако в строгом режиме вы получите сообщение об ошибке и не дойдете до строки console.log.

Свойство, доступное только для получения

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

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

Только для чтения означает, что для атрибута свойства объекта, доступного для записи, установлено значение false — его нельзя изменить.

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

В строгом режиме мы получим ошибку.

Нерасширяемый объект

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

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

И тогда мы получаем ошибку.

Удаление свойства объекта

Свойства объекта, для атрибута которых установлено значение false, не могут быть удалены. Этот атрибут определяет, можно ли удалить атрибут. Как и в приведенных выше примерах, если мы попытаемся удалить неконфигурируемый атрибут, он не будет удален, но и не выдаст ошибку!

Однако в строгом режиме мы увидим ошибку:

Повторяющиеся параметры

В неаккуратном режиме, если мы повторим имена параметров, мы больше не увидим никакой ошибки!

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

Утечка оценок

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

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

Однако в строгом режиме не допускается:

Назначение/привязка оценок и аргументов

Помимо ограниченного использования строк eval, мы также не можем присвоить какое-либо значение объекту eval, а также объекту аргументов.

Без строгого режима он будет работать отлично:

В строгом режиме до console.log не дойдет:

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

Свойства примитивных значений

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

Примитивные значения — это типы данных, которые представляют одно значение — неопределенное, нулевое, логическое, строковое, число и символ.

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

Как только мы включим строгий режим, мы увидим ошибку:

Синхронизация индексов параметров и аргументов

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

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

Давайте рассмотрим пример ниже, где мы используем небрежный режим:

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

У нас есть параметр «a», которому мы передали аргумент 1. В теле функции мы пытаемся переприсвоить значение параметру со значением 12.

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

Другими словами, в обоих случаях мы пытались изменить значение параметра «a» — сначала через имя параметра, а затем через объект и индекс аргументов. В результате мы везде получаем значение 13, поскольку это было последнее присвоенное нами значение.

Теперь посмотрите, что происходит в строгом режиме!

Что здесь происходит? Мы пытаемся сделать то же самое, но получаем странные результаты. Попытка переназначить значение параметру «a» не удалась. Почему?

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

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

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

Это ключевое слово

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

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

Свойства обхода стека

Функции в JavaScript имеют свойство caller. Он возвращает ссылку на функцию, которую мы вызываем целевой функцией. Вот пример:

Он вернет ссылку на функцию, откуда функция была вызвана, в нашем случае мы вызвали функцию из callerFunc:

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

Вот что происходит в строгом режиме:

У нас также есть еще одно свойство под названием callee. Раньше это свойство было полезно для рекурсивных функций, когда функции требовалось получить доступ к самой себе или обратиться к ней. Рекурсивная функция — это функция, которая вызывает сама себя до тех пор, пока не будет выполнено определенное условие.

Вот пример рекурсивной функции со свойством вызываемого объекта, которая вызывает себя до тех пор, пока не достигнет единицы, и возвращает сумму каждого числа от 1 до числа, которое мы ей передали:

Мы больше не можем делать это в строгом режиме:

Больше зарезервированных слов

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

Например, вы не можете создавать переменные с такими именами, как const, try, this, true и т. д.

Строгий режим добавляет еще больше зарезервированных слов:

  • интерфейс
  • реализует
  • позволять
  • упаковка
  • частный
  • защищенный
  • общественный
  • статический
  • урожай

Плюсы и минусы строгого режима

Действительно ли нам нужен строгий режим или это дополнительный уровень сложности?

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

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

Заключение

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

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

Это также помогает контролировать ключевое слово this и не отсылает его к глобальному объекту.

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