Строгий режим ('use strict') — специальный режим исполнения кода, введённый в ES5 (2009 год). Он меняет несколько сомнительных default-поведений JavaScript, и главное для этой темы — в строгом режиме this при простом вызове функции становится undefined, а не глобальным объектом:

'use strict';

function checkContext() {
  console.log(this);   // => undefined (в строгом режиме)
}

checkContext();

// пробуем присвоить свойство this — TypeError
function assign() {
  this.color = 'red';  // TypeError: Cannot set properties of undefined
}
assign();

Идея простая: если ты забыл вызвать функцию как метод объекта или через .call() — строгий режим сразу ловит эту ошибку, а не тихо создаёт свойство глобального объекта. Проблема, разобранная в подглаве 2.1, становится видимой ошибкой на этапе выполнения.

Как включить строгий режим

Директива 'use strict' ставится первой строкой — либо в файле (влияет на весь скрипт), либо внутри функции (влияет только на её тело):

// на уровне файла
'use strict';
function outer() { /* ... */ }

// или внутри функции
function outer() {
  'use strict';
  // здесь строгий режим
}

Директива — литерал строки, а не оператор. Никаких эффектов у неё в браузере нет, кроме включения строгого режима.

Где строгий режим включён автоматически

Написание 'use strict' руками нужно всё реже — современные форматы кода включают его сами:

  • ES-модули (<script type="module">, файлы .mjs, "type": "module" в package.json) — всегда строгий режим. Директива внутри модуля не нужна.
  • Тело class — конструктор и все методы работают в строгом режиме, независимо от того, стоит директива снаружи или нет.
  • TypeScript-файлы компилируются в строгий режим по умолчанию.
  • Bundler-код (Webpack, Rollup, Vite, esbuild) обычно оборачивает исходники в строгий режим при сборке.

Практическое следствие: в новом коде — во фронт-модулях, в TypeScript-проектах, в class-based-компонентах — строгий режим уже работает. Директиву руками писать не нужно, а поведение this в «простом вызове» = undefined — норма.

Что даёт этот сдвиг

Есть две практические выгоды от undefined вместо глобального объекта:

Ошибки видны сразу. В нестрогом режиме this.myProp = 'value' при простом вызове тихо создаёт window.myProp. Bug живёт, пока кто-то не заметит «появившуюся из ниоткуда» глобальную переменную. В строгом режиме та же строка кидает TypeError — ошибка на месте, стек-трейс сразу указывает на строку.

// нестрогий режим — молчаливая ошибка
function saveConfig(config) {
  this.currentConfig = config;   // тихо создаёт window.currentConfig
}
saveConfig({ theme: 'dark' });   // проблема живёт незамеченной

// строгий режим — явная ошибка
'use strict';
function saveConfig(config) {
  this.currentConfig = config;   // TypeError на этой строке
}
saveConfig({ theme: 'dark' });

Оптимизация V8. Строгий режим позволяет движку V8 (и другим современным движкам) применять более агрессивные оптимизации. Разница на реальном коде редко заметна, но в hot-paths может составлять несколько процентов.

Как воспринимать ошибки

Ошибка TypeError: Cannot set properties of undefined (setting 'X') в новом коде — почти всегда сигнал одной из трёх проблем:

  1. Забыли new при вызове конструктора. const u = User('Аня') вместо new User('Аня') — см. подглаву 4.2.
  2. Отделили метод от объекта. const fn = obj.method; fn() — см. подглаву 3.2.
  3. Вложенная функция в методе объекта. Обычная функция внутри метода потеряла контекст — см. подглаву 2.3.

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