Avatar ·

Что делает "use strict" в JavaScript и зачем он нужен?

Всем привет! Я начал изучать JavaScript и заметил, что в некоторых примерах кода в начале файла или функции пишут `'use strict';`. Честно говоря, я не совсем понимаю, зачем это нужно и что это вообще делает. Я попробовал написать простой скрипт без этой директивы, и всё работало. Например, я случайно создал переменную без `let`, `const` или `var`: ```javascript function test() { myVar = 10; // Я забыл написать let console.log(myVar); } test(); // Выведет 10 ``` Но если я добавляю `'use strict';`: ```javascript 'use strict'; function test() { myVar = 10; // Ошибка! console.log(myVar); } test(); // ReferenceError: myVar is not defined ``` Теперь код падает с ошибкой. Вроде бы без `'use strict'` всё работало проще, но я слышал, что опытные разработчики настоятельно рекомендуют его использовать. В чём подвох? Почему нужно усложнять себе жизнь, если и так всё работает? Какие ещё "ловушки" JavaScript он исправляет? И когда его стоит применять — всегда или есть исключения? Буду благодарен за подробное объяснение для новичка! <<>>

Что такое "use strict" и как он работает?

Директива 'use strict'; (строгий режим) была введена в ECMAScript 5 (ES5) как способ добровольного перехода к более безопасной и строгой версии JavaScript. Она заставляет интерпретатор обрабатывать код с дополнительными проверками, превращая многие "тихие" ошибки в явные исключения. Это не просто "каприз" — это защита от распространённых багов, которые трудно отловить.

Основные улучшения строгого режима

  • Запрет неявного создания глобальных переменных: Как в вашем примере. Без 'use strict' присваивание значения необъявленной переменной автоматически создаёт глобальную переменную. Это может привести к трудноуловимым багам, особенно в больших скриптах.
  • Запрет удаления переменных, функций и аргументов: Оператор delete не может удалить обычные переменные. В строгом режиме это вызовет ошибку, а не просто вернёт false.
  • Запрет дублирования имён параметров функции: function sum(a, a, c) {} в строгом режиме вызовет SyntaxError. В нестрогом режиме последнее значение перезапишет предыдущие.
  • Запрет записи в readonly-свойства: Попытка изменить свойство, которое помечено как writable: false (например, undefined = 5), вызовет ошибку, а не проигнорируется.
  • Безопасная работа с this: В функциях, вызванных как обычные функции (не как методы объекта), this будет undefined, а не глобальный объект (window в браузере). Это предотвращает случайное изменение глобального состояния.
  • Запрет использования with: Конструкция with(obj) { ... } полностью запрещена, так как она создаёт путаницу в области видимости и замедляет выполнение кода.
  • Дополнительные ограничения на eval: В строгом режиме eval не может создавать переменные в окружающей области видимости. Он работает в изолированном "пузыре".

Примеры кода: строгий vs нестрогий режим

// Пример 1: this в обычной функции
function showThis() {
    console.log(this);
}
showThis(); 
// Нестрогий режим: window (глобальный объект)
// Строгий режим: undefined

// Пример 2: Запрет удаления переменной
'use strict';
var x = 10;
delete x; // SyntaxError: Delete of an unqualified identifier in strict mode.

// Пример 3: Дублирование параметров
'use strict';
function foo(a, a) {} // SyntaxError: Duplicate parameter name not allowed

// Пример 4: eval не загрязняет область видимости
'use strict';
eval('var y = 5');
console.log(y); // ReferenceError: y is not defined

Когда и как использовать

Рекомендуется включать строгий режим всегда, особенно в новом коде. Есть два способа:

  • Глобально — для всего файла: 'use strict'; в самом начале скрипта. Но будьте осторожны: если вы объединяете несколько скриптов, строгий режим может "перекинуться" на чужой код, который написан в нестрогом стиле.
  • Локально — только внутри функции: function myFunc() { 'use strict'; ... }. Это безопаснее при работе с чужим кодом.

В современных ES6-модулях (когда вы используете <script type="module"> или импорты) строгий режим включён по умолчанию. В классах (ES6) он также активен автоматически.

Итог: 'use strict' — это не усложнение, а страховка. Он превращает многие "тихие" ошибки в явные, которые вы можете сразу исправить, а не искать потом неделями. Всегда используйте его в новом коде, и ваша жизнь станет проще.

<<>>

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

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

Производительность. Вопреки мнению, что "дополнительные проверки замедляют код", в современных движках (V8, SpiderMonkey) строгий режим часто работает быстрее. Почему? Потому что он упрощает оптимизацию: движок знает, что некоторые "опасные" конструкции (например, with или arguments.callee) не будут использоваться, и может агрессивнее оптимизировать код. Так что это ещё и бонус к скорости.

Совместимость. Если вы пишете код для очень старых браузеров (Internet Explorer 9 и ниже), они проигнорируют директиву 'use strict' и будут выполнять код в нестрогом режиме. Это не страшно — ваш код просто будет работать как обычно (но без защиты). Проблемы начинаются, когда вы наоборот: пишете код, который требует строгий режим (например, используете ES6-классы), и запускаете его в старом браузере. Тут будет SyntaxError.

Рекомендация: Начинайте каждую новую функцию или модуль с 'use strict';. Если пишете на ES6+ — используйте модули, и строгий режим включится сам. Не бойтесь ошибок — это ваш друг, а не враг. Удачи в изучении JavaScript!