Skip to main content

Директива use strict

"use strict" це директива, яка вмикає строгий режим інтерпретації JavaScript: this у звичайній функції стає undefined замість глобального об'єкта, а присвоєння неоголошеній змінній стає помилкою замість неявного створення глобальної змінної. Строгий режим допомагає писати безпечніший і передбачуваніший код, бо усуває «тихі» помилки і стару неочевидну поведінку.

Теорія

TL;DR

  • Директива діє в межах файлу або функції, на початку якої вона написана.
  • this у звичайному виклику функції стає undefined, а не глобальним об'єктом; у методах і стрілкових функціях нічого не змінюється.
  • Присвоєння неоголошеній змінній кидає ReferenceError, замість того щоб створити глобальну змінну.
  • Заборонені: дублікати імен параметрів, delete змінної або функції, присвоєння в undefined, NaN, Infinity, оператор with.
  • eval отримує власну область видимості і більше не забруднює довколишній scope.

Швидкий приклад

javascript
'use strict'; function showThis() { console.log(this); } showThis(); // undefined function test() { x = 10; // ReferenceError: x is not defined } test();

Директиву ставлять першим рядком файлу:

javascript
'use strict';

або першим рядком функції:

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

У модулях ES і в тілах класів строгий режим увімкнений завжди, писати директиву там не треба.

Головна зміна: поведінка this

КонтекстБез "use strict"З "use strict"
У звичайній функціїthis -> глобальний об'єкт (window у браузері)this -> undefined
У методі об'єктаthis -> сам об'єктthis -> той самий об'єкт, без змін
У стрілковій функціїуспадковується ззовніуспадковується ззовні, без змін

Приклад без строгого режиму:

javascript
function showThis() { console.log(this); } showThis(); // глобальний об'єкт (window у браузері)

Тут рушій «підставляє» глобальний об'єкт за замовчуванням.

Приклад зі строгим режимом:

javascript
'use strict'; function showThis() { console.log(this); } showThis(); // undefined

У строгому режимі, якщо функцію викликано не як метод об'єкта, this лишається undefined: жодних неявних «магічних» прив'язок. Це рятує від випадкових звернень до глобального об'єкта (window у браузері, global у Node.js) і від непомітного створення глобальних властивостей.

Заборона неявних глобальних змінних

Без строгого режиму:

javascript
function test() { x = 10; // змінна створиться глобально! console.log(x); } test(); console.log(globalThis.x); // 10

Зі строгим режимом:

javascript
'use strict'; function test() { x = 10; // ReferenceError: x is not defined } test();

Тепер змінні треба оголошувати явно через let, const або var, інакше буде помилка. Це прибирає цілий клас багів, коли одна друкарська помилка в імені змінної мовчки створює нову глобальну змінну.

Синтаксичні заборони: дублікати, delete і with

Дублікати імен параметрів. Без строгого режиму:

javascript
function sum(a, a, c) { return a + a + c; } console.log(sum(1, 2, 3)); // 7

Зі строгим режимом:

javascript
'use strict'; function sum(a, a, c) { // SyntaxError return a + a + c; }

Видалення змінних, функцій і параметрів. Без строгого режиму:

javascript
var a = 1; delete a; // false

Зі строгим режимом:

javascript
'use strict'; var a = 1; delete a; // SyntaxError

У строгому режимі не можна видаляти те, що не є властивістю об'єкта. Оператор with також заборонений повністю, бо він робить область видимості непередбачуваною.

Тихі помилки стають гучними

Присвоєння в undefined, NaN та Infinity:

javascript
'use strict'; undefined = 5; // TypeError NaN = 123; // TypeError Infinity = 42; // TypeError

Порівняння поведінки:

СитуаціяБез "use strict"З "use strict"
Присвоєння в NaN, undefined, Infinityтихо ігноруєтьсяпомилка
Присвоєння в constігноруєтьсяпомилка
Оператор withдозволенозаборонено
Видалення властивостей, які не можна видалятитихо ігноруєтьсяпомилка

Головна ідея строгого режиму саме в цьому: операція, яка раніше нічого не робила і нічого не повідомляла, тепер одразу падає з помилкою, і баг видно під час розробки, а не в продакшені.

Безпечніший eval і підсумкова таблиця

Без строгого режиму eval може створювати змінні у поточному контексті:

javascript
eval('var x = 10;'); console.log(x); // 10

Зі строгим режимом eval створює власну область видимості:

javascript
'use strict'; eval('var x = 10;'); console.log(x); // ReferenceError

Це не дає випадково забруднити довколишнє оточення.

Що змінює "use strict"Поведінка
this у звичайних функціяхundefined замість глобального об'єкта
Неоголошені змінніПомилка
Дублікати параметрівПомилка
Видалення змінних і функційПомилка
Присвоєння в NaN, undefined, InfinityПомилка
evalСтворює власний scope
withЗаборонений

Типові помилки

  • Ставити директиву не першим рядком файлу чи функції: тоді це просто рядковий літерал, і строгий режим не вмикається.
  • Вважати, що "use strict" діє на весь проєкт. Він діє тільки в межах свого файлу або своєї функції.
  • Дописувати директиву в модуль ES або в клас: там строгий режим уже увімкнений за специфікацією.
  • Забувати, що в строгому режимі this у звичайній функції це undefined, і звертатись до this.something після втрати контексту: замість непомітного глобального об'єкта отримаєте TypeError.
  • Конкатенувати файли, з яких хоча б один починається з "use strict": директива на початку результату може несподівано перевести в строгий режим увесь бандл.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.