Директива use strict
"use strict" це директива, яка вмикає строгий режим інтерпретації JavaScript: this у звичайній функції стає undefined замість глобального об'єкта, а присвоєння неоголошеній змінній стає помилкою замість неявного створення глобальної змінної. Строгий режим допомагає писати безпечніший і передбачуваніший код, бо усуває «тихі» помилки і стару неочевидну поведінку.
Теорія
TL;DR
- Директива діє в межах файлу або функції, на початку якої вона написана.
thisу звичайному виклику функції стаєundefined, а не глобальним об'єктом; у методах і стрілкових функціях нічого не змінюється.- Присвоєння неоголошеній змінній кидає
ReferenceError, замість того щоб створити глобальну змінну. - Заборонені: дублікати імен параметрів,
deleteзмінної або функції, присвоєння вundefined,NaN,Infinity, операторwith. evalотримує власну область видимості і більше не забруднює довколишній scope.
Швидкий приклад
'use strict';
function showThis() {
console.log(this);
}
showThis(); // undefined
function test() {
x = 10; // ReferenceError: x is not defined
}
test();Директиву ставлять першим рядком файлу:
'use strict';або першим рядком функції:
function foo() {
'use strict';
// строгий режим діє тільки всередині цієї функції
}У модулях ES і в тілах класів строгий режим увімкнений завжди, писати директиву там не треба.
Головна зміна: поведінка this
| Контекст | Без "use strict" | З "use strict" |
|---|---|---|
| У звичайній функції | this -> глобальний об'єкт (window у браузері) | this -> undefined |
| У методі об'єкта | this -> сам об'єкт | this -> той самий об'єкт, без змін |
| У стрілковій функції | успадковується ззовні | успадковується ззовні, без змін |
Приклад без строгого режиму:
function showThis() {
console.log(this);
}
showThis(); // глобальний об'єкт (window у браузері)Тут рушій «підставляє» глобальний об'єкт за замовчуванням.
Приклад зі строгим режимом:
'use strict';
function showThis() {
console.log(this);
}
showThis(); // undefinedУ строгому режимі, якщо функцію викликано не як метод об'єкта, this лишається undefined: жодних неявних «магічних» прив'язок. Це рятує від випадкових звернень до глобального об'єкта (window у браузері, global у Node.js) і від непомітного створення глобальних властивостей.
Заборона неявних глобальних змінних
Без строгого режиму:
function test() {
x = 10; // змінна створиться глобально!
console.log(x);
}
test();
console.log(globalThis.x); // 10Зі строгим режимом:
'use strict';
function test() {
x = 10; // ReferenceError: x is not defined
}
test();Тепер змінні треба оголошувати явно через let, const або var, інакше буде помилка. Це прибирає цілий клас багів, коли одна друкарська помилка в імені змінної мовчки створює нову глобальну змінну.
Синтаксичні заборони: дублікати, delete і with
Дублікати імен параметрів. Без строгого режиму:
function sum(a, a, c) {
return a + a + c;
}
console.log(sum(1, 2, 3)); // 7Зі строгим режимом:
'use strict';
function sum(a, a, c) { // SyntaxError
return a + a + c;
}Видалення змінних, функцій і параметрів. Без строгого режиму:
var a = 1;
delete a; // falseЗі строгим режимом:
'use strict';
var a = 1;
delete a; // SyntaxErrorУ строгому режимі не можна видаляти те, що не є властивістю об'єкта. Оператор with також заборонений повністю, бо він робить область видимості непередбачуваною.
Тихі помилки стають гучними
Присвоєння в undefined, NaN та Infinity:
'use strict';
undefined = 5; // TypeError
NaN = 123; // TypeError
Infinity = 42; // TypeErrorПорівняння поведінки:
| Ситуація | Без "use strict" | З "use strict" |
|---|---|---|
Присвоєння в NaN, undefined, Infinity | тихо ігнорується | помилка |
Присвоєння в const | ігнорується | помилка |
Оператор with | дозволено | заборонено |
| Видалення властивостей, які не можна видаляти | тихо ігнорується | помилка |
Головна ідея строгого режиму саме в цьому: операція, яка раніше нічого не робила і нічого не повідомляла, тепер одразу падає з помилкою, і баг видно під час розробки, а не в продакшені.
Безпечніший eval і підсумкова таблиця
Без строгого режиму eval може створювати змінні у поточному контексті:
eval('var x = 10;');
console.log(x); // 10Зі строгим режимом eval створює власну область видимості:
'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": директива на початку результату може несподівано перевести в строгий режим увесь бандл.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.