Read 9 min
Директива "use strict"
"use strict"
- це директива, яка була додана до JavaScript у стандарті "ECMAScript 5th Edition (ES5)"
Список всіх стандартів JavaScript доступний за цим посиланням.
Її мета - повідомити інтерпритатору що код, який слідує за нею, треба обробити в "строгому режимі".
Строгий режим працює наступним чином:
- виправляє деякі недоліки JavaScript
- забороняє використовувати деякі елементи синтаксису
- забезпечує більш сувору перевірку на наявність помилок
Строгий режим можна увімкнути як для всього тегу <script>
або файлу,
<script>
'use strict';
// Увімкнули строгий режим для всього тега скрипт
</script>
так і для окремої функції за допомогою директиви `"use strict"'
// Звичайний режим тут
function mySuperFoo () {
'use strict';
// Строгий режим тут
}
// Звичайний режим тут
Важливо: Директива "use strict"
повинна знаходитися на початку (на першому рядку, що виконується)
файлу або тегу <script>
, або на першому рядку функції, що виконується.
Давайте подивимося, чим строгий режим відрізняється від звичайного режиму.
У строгому режимі не можна створити глобальну змінну
У строгому режимі не можна створити глобальну змінну, або іншими словами, змінну
без використання ключових слів var
, let
або const
.
'use strict'
myLonelyVariable = 1; // Uncaught ReferenceError: myLonelyVariable is not defined
Таке оголошення в строгому режимі кине помилку "Uncaught ReferenceError". У звичайному режимі, не строгому, така спроба створить нову глобальну змінну і додасть її як властивості в глобальний об'єкт.
У строгому режимі функції не отримують посилання на глобальний об'єкт як значення this
У строгому режимі, функції що викликаються як функції, а не як методи об'єктів,
отримають undefined
як значення this
'use strict'
function getName () {
console.log(this);
}
getName(); // undefined
Більш того, в строгому режимі, значення this
завжди відповідає значенню, переданому як контекст виконання в
методах call
, apply
та bind
'use strict'
function getName () {
console.log(this);
}
getName.call(undefined); // undefined
getName.apply(null); // null
getName.bind()(); // undefined
А в несуворому режимі null
та undefined
будуть замінені посиланням на глобальний об'єкт.
function getName () {
console.log(this);
}
getName.call(undefined); // Window
getName.apply(null); // Window
getName.bind()(); // Window
У строгому режимі функціональні вирази видно лише всередині блоку
У строгому режимі функціональні вирази (Function Declaration) видно лише всередині блоку,
в якому оголошено, тому в прикладі нижче ми отримаємо помилку ReferenceError
'use strict'
if (true) {
function hi() {
console.error('hi 👋');
}
}
hi(); // Uncaught ReferenceError: hi is not defined
Без "use strict"
ми побачили би у консолі "hi 👋"
В строгом режиме нельзя присвоить значения свойствам, которые недоступны для записи
У строгому режимі не можна надати значення властивостям, які недоступні для запису, або створити властивості в нерозширюваних об'єктах
'use strict'
Infinity = 1; // Uncaught TypeError: Cannot assign to read only property 'Infinity' of object '#<Window>'
const obj = {};
const frozenObj = Object.freeze(obj);
frozenObj.newProp = 1; // Uncaught TypeError: Cannot add property newProp, object is not extensible
В обох випадках у строгому режимі такі операції викличуть помилку TypeError, а у звичайному режимі таке присвоєння просто буде проігноровано.
У строгому режимі псевдомасив arguments
зберігає статичну копію значень
У суворому режимі псевдомасив arguments
зберігає статичну копію значень аргументів, переданих у функцію.
'use strict'
function foo(x) {
console.log(x === arguments[0]); // true
arguments[0] = 2;
console.log(x === arguments[0]); // false
console.log(x); // 1
}
foo(1);
У прикладі вище у рядку 5 ми перевизначили значення arguments[0]
, причому значення x
не змінилося.
У звичайному режимі, не строгому, елементи arguments
та іменовані параметри функції посилаються на ті самі значення,
тому перевизначення торкнулося б значення x
.
У строгому режимі визначення двох або більше параметрів з однаковими іменами в оголошенні функції є синтаксичною помилкою.
'use strict'
function foo(x, x) {
console.error('x', x);
console.error('x', x);
}
foo(1, 2);
У звичайному режимі, помилка не виникає.
Менш значущі особливості роботи строгого режиму
- У строгому режимі не можна використовувати конструкцію
with
.
Якщо ви не чули про неї, то, можливо, вже і не варто про неї турбуватися, але на всякий випадок залишу посилання
- Також у строгому режимі усунуті деякі моменти, пов'язані з поведінкою методу
eval
.
Без "use strict"
у eval
не буде свого лексичного оточення, тому змінні,
оголошені всередині eval
, можуть перевизначити змінні лексичного оточення батьківської функції.
-
У строгому режимі властивості
arguments.callee
таarguments.callee.caller
більше не підтримуються -
У строгому режимі заборонено використовувати такі зарезервовані слова:
implements
, let
, interface
, package
, private
, protected
, public
, static
, yield
Висновок
Всі ці особливості роботи строгого та звичайного режимів важливі для розуміння тонкощів мови JavaScript, але на практиці, в більшості випадків, ми працюємо з класами та модулями, а у них строгий режим увімкнено за замовчуванням.