Что делает директива ‘use strict’ в JavaScript, каковы её последствия, и она всё ещё актуальна в современных браузерах?
Директива ‘use strict’ в JavaScript
Директива ‘use strict’ в JavaScript включает строгий режим, который обеспечивает лучшую проверку ошибок, устраняет тихие ошибки и повышает безопасность, ограничивая определенные языковые возможности. Она предотвращает использование потенциально проблемных возможностей JavaScript и упрощает отладку, преобразуя тихие ошибки в исключения. Несмотря на то, что ES6-модули автоматически включают строгий режим, директива ‘use strict’ остается актуальной для немодульного кода и как явное выражение намерения поддерживать чистые, устойчивые к ошибкам JavaScript-приложения.
Содержание
- Что такое директива ‘use strict’?
- Как реализовать строгий режим
- Ключевые особенности и последствия
- Различия в обработке ошибок
- Вопросы производительности
- Актуальность в современной разработке на JavaScript
Что такое директива ‘use strict’?
Директива ‘use strict’ — это литеральное выражение, которое включает строгий режим JavaScript. Введенная в ECMAScript 5 (ES5), она была разработана для решения проблем гибкости языка, которые могли приводить к программным ошибкам или уязвимостям в безопасности. Когда включен строгий режим, JavaScript-движок применяет более строгие правила разбора и обработки ошибок, чем в обычном (нестрогом) режиме.
Эта директива не является оператором, а литеральным выражением, которое должно появляться в самом начале скрипта или тела функции. При размещении вверху скрипта она влияет на весь скрипт. При размещении внутри функции она влияет только на эту функцию и ее вложенные функции.
Важно: Директива ‘use strict’ должна быть первым оператором в скрипте или функции. Разрешены любые предыдущие комментарии или пробельные символы, но никаких других выполняемых операторов перед ней не допускается.
Исторически JavaScript был разработан с перmissive-подходом для минимизации ошибок в ранней веб-разработке. Хотя этот подход делал JavaScript более простым для написания начинающими, он также позволял многочисленные тихие сбои и потенциально опасные практики. Строгий режим был введен для компенсации этого путем предоставления “безопасного” подмножества JavaScript с более строгой обработкой ошибок.
Как реализовать строгий режим
Реализация строгого режима в JavaScript проста. Просто добавьте директиву ‘use strict’ в качестве первого оператора в вашем скрипте или функции:
Строгий режим на уровне скрипта
'use strict';
// Весь код в этом скрипте будет выполняться в строгом режиме
let x = 10;
console.log(x); // 10
Строгий режим на уровне функции
function strictFunction() {
'use strict';
// Эта функция и все вложенные функции выполняются в строгом режиме
let y = 20;
console.log(y); // 20
}
function nonStrictFunction() {
// Эта функция выполняется в нестрогом режиме
let z = 30;
console.log(z); // 30
}
Строгий режим на уровне класса
В ES6 определения классов автоматически выполняются в строгом режиме, даже без явного объявления ‘use strict’:
class MyClass {
constructor() {
// Этот код автоматически выполняется в строгом режиме
this.value = 42;
}
}
ES-модули
ES-модули (файлы с расширением .mjs или с type=“module” в тегах script) автоматически выполняются в строгом режиме:
<script type="module">
// Этот код автоматически выполняется в строгом режиме
import { something } from './module.js';
</script>
Примечание: При использовании ‘use strict’ в сочетании с другими языковыми возможностями или инструментами убедитесь в их совместимости. Некоторые транспиляторы, такие как Babel, автоматически включают строгий режим при выборе определенных целей синтаксиса.
Ключевые особенности и последствия
Строгий режим вводит несколько значительных изменений в поведение JavaScript, которые помогают разработчикам писать более надежный и поддерживаемый код:
Объявление переменных
В строгом режиме все переменные должны быть объявлены перед использованием. Необъявленные переменные вызовут ReferenceError вместо создания глобальных свойств:
'use strict';
// В строгом режиме это вызовет ReferenceError
undeclaredVar = 10; // Error: undeclaredVar is not defined
В нестрогом режиме это создало бы глобальную переменную undeclaredVar
.
Привязка ‘this’
Строгий режим изменяет поведение this
в функциях:
- В глобальных функциях
this
равноundefined
вместо глобального объекта:
'use strict';
function test() {
console.log(this); // undefined
}
test();
- В конструкторах, вызываемых без
new
,this
не приводится к глобальному объекту:
'use strict';
function Constructor() {
console.log(this); // undefined
}
Constructor(); // Вызывает TypeError: Cannot read properties of undefined (reading 'constructor')
Параметры функции
Строгий режим запрещает дублирование имен параметров в объявлениях функций:
'use strict';
function duplicateParams(a, a) { // SyntaxError: Duplicate parameter name not allowed in this context
// ...
}
Операции записи в свойства
Строгий режим предотвращает запись в свойства только для чтения и добавление свойств к нерасширяемым объектам:
'use strict';
'use strict';
// Запись в свойство только для чтения
'use strict';
var obj1 = {};
Object.defineProperty(obj1, 'prop', { value: 10, writable: false });
obj1.prop = 20; // TypeError: Cannot assign to read only property 'prop' of object
// Добавление свойства к нерасширяемому объекту
var obj2 = { a: 1 };
Object.preventExtensions(obj2);
obj2.b = 2; // TypeError: Cannot add property b, object is not extensible
Оператор ‘with’
Строгий режим полностью отключает оператор with
, который может привести к неоднозначному коду и проблемам с производительностью:
'use strict';
with (Math) { // SyntaxError: Strict mode code may not include a with statement
let x = random();
}
Восьмеричные литералы
Строгий режим запрещает восьмеричные литералы (кроме литерала 0
):
'use strict';
let octal = 0755; // SyntaxError: Octal literals are not allowed in strict mode.
Объект arguments
Строгий режим изменяет поведение объекта arguments
. Он больше не отслеживает изменения значений параметров:
'use strict';
function test(a) {
a = 20;
console.log(arguments[0]); // 1, а не 20
}
test(1);
Различия в обработке ошибок
Одним из самых значительных улучшений строгого режима является его улучшенная обработка ошибок. В строгом режиме многие тихие ошибки, которые игнорировались бы в нестрогом режиме, преобразуются в явные исключения:
Тихие ошибки становятся исключениями
- Присваивание свойству, доступному только для чтения, вызывает TypeError вместо тихого сбоя
- Присваивание свойству только с геттером вызывает TypeError
- Добавление свойства к нерасширяемому объекту вызывает TypeError
- Дублирование имен параметров вызывает SyntaxError
- Использование
eval
илиarguments
в качестве имени переменной или параметра функции вызывает SyntaxError
Лучшие сообщения об ошибках
Строгий_mode часто предоставляет более описательные сообщения об ошибках, что упрощает отладку:
'use strict';
// В нестрогом режиме могут возникать запутанные или неясные ошибки
// Строгий режим предоставляет более четкую и конкретную информацию об ошибках
Устранение принудительной привязки ‘this’
Как упоминалось ранее, строгий режим предотвращает автоматическое приведение this
к глобальному объекту при вызовах функций, что помогает предотвратить случайные модификации глобального объекта:
'use strict';
function() {
this.globalVar = "oops"; // TypeError: Cannot set property 'globalVar' of undefined
}
Вопросы производительности
Строгий режим был разработан не только для безопасности, но и для производительности. Хотя улучшения производительности обычно незначительны, в некоторых сценариях они могут быть существенными:
Оптимизации
JavaScript-движки могут выполнять определенные оптимизации, когда знают, что код выполняется в строгом режиме:
- Некоторые ссылки на переменные могут быть разрешены быстрее
- Определенные привязки
this
упрощаются - Поведение объекта arguments более предсказуемо
Использование памяти
Строгий режим иногда может привести к снижению использования памяти:
- Объект arguments не нужно отслеживать изменения параметров
- Некоторые оптимизации движка снижают накладные расходы на память
Важно: Хотя строгий режим может предлагать преимущества производительности, его основная ценность заключается в качестве кода и предотвращении ошибок. Производительность не должна быть основной причиной выбора строгого режима.
Актуальность в современной разработке на JavaScript
Несмотря на современные стандарты JavaScript и браузеры, директива ‘use strict’ остается highly актуальной по нескольким причинам:
Автоматический строгий режим в современных контекстах
Некоторые современные возможности JavaScript автоматически включают строгий режим:
- ES-модули: Все ES-модули по умолчанию выполняются в строгом режиме
- Классы: Определения классов и методы автоматически используют строгий режим
- Стрелочные функции: Стрелочные функции наследуют строгий режим от окружающего контекста
Преимущества для качества кода
Строгий режим обеспечивает лучшие практики кодирования, которые необходимы для крупномасштабных приложений:
- Предотвращает случайное создание глобальных переменных
- Устраняет тихие сбои, которые могут быть трудно отлаживаемы
- Делает код более предсказуемым и легким для поддержки
Совместимость с современными инструментами
Современные инструменты разработки и фреймворки часто предполагают или требуют строгий режим:
- Транспиляция TypeScript использует строгий режим
- Многие правила ESLint обеспечивают соблюдение практик строгого режима
- Сборщики, такие как Webpack, часто включают строгий режим по умолчанию
Будущая совместимость кода
По мере эволюции JavaScript строгий режим обеспечивает основу для более безопасного кода:
- Новые языковые возможности разрабатываются с учетом строгого режима
- Спецификация ECMAScript продолжает совершенствовать поведение строгого режима
- Браузерные движки оптимизированы для кода в строгом режиме
Когда использовать строгий режим
Несмотря на автоматическое включение в некоторых контекстах, все еще существуют ситуации, когда явное ‘use strict’ полезно:
- Наследуемые кодовые базы: При работе со старым кодом, который не использует модули или классы
- Немодульные скрипты: Для скриптов, которые не являются модулями, но должны следовать строгим практикам
- Разработка библиотек: Чтобы гарантировать предсказуемое поведение библиотек независимо от того, как они используются
- Обучение: Для изучающих, которые хотят понять современные лучшие практики JavaScript
Когда строгий режим может быть не нужен
В некоторых случаях строгий режим уже включен или не требуется:
- ES-модули: Уже в строгом режиме
- Определения классов: Уже в строгом режиме
- Быстрые прототипы: Для очень временных, небольших скриптов, где требуется максимальная гибкость
Заключение
Директива ‘use strict’ остается важной частью современной разработки на JavaScript, несмотря на автоматическое включение в нескольких контекстах. Ее основные преимущества включают:
- Лучшая обработка ошибок: Преобразует тихие сбои в явные исключения
- Улучшения безопасности: Предотвращает случайное создание глобальных переменных
- Качество кода: Обеспечивает лучшие практики кодирования и устраняет проблемные языковые возможности
- Возможности оптимизации: Включает определенные оптимизации производительности в JavaScript-движках
Для современной разработки на JavaScript:
- Используйте ‘use strict’ явно в немодульных скриптах и наследуемом коде
- Понимайте, что ES-модули, классы и стрелочные функции автоматически используют строгий режим
- Рассматривайте строгий режим как часть стандартов кодирования и правил линтинга
- Используйте строгий режим для раннего обнаружения потенциальных проблем в процессе разработки
По мере продолжения эволюции JavaScript строгий режим обеспечивает основу для написания более безопасного и поддерживаемого кода, который будет надежно работать в разных средах и браузерах.