Пошук уроків, статей та іншого контенту
Визначите значення this у глобальному коді, звичайних функціях і суворому режимі виконання.
thisthis — це спеціальне значення, яке вказує на об’єкт, пов’язаний із поточним виконанням коду.
На відміну від звичайних змінних, значення this визначається не місцем оголошення функції, а способом її виклику. Для початку розглянемо глобальний код і звичайні функції.
У прикладах у браузері мається на увазі звичайний JavaScript-файл, підключений через
<script>, а не JavaScript-модуль.
this у глобальному кодіГлобальний код — це код, який виконується не всередині функції:
console.log("Це глобальний код");
const language = "JavaScript";
console.log(this);У браузері в звичайному скрипті глобальним об’єктом є window. Також до нього можна звернутися через універсальне ім’я globalThis.
console.log(this === window); // true
console.log(this === globalThis); // trueГлобальний об’єкт містить властивості та API, доступні в усьому середовищі браузера: console, setTimeout, location та інші.
var і letУ браузерному звичайному скрипті змінні, оголошені через var, стають властивостями глобального об’єкта:
var oldVariable = "значення var";
let modernVariable = "значення let";
console.log(globalThis.oldVariable); // "значення var"
console.log(globalThis.modernVariable); // undefinedЗмінні, оголошені через let, const або class, не стають властивостями globalThis.
Це не змінює значення this у глобальному коді: у браузерному звичайному скрипті воно все одно вказує на глобальний об’єкт.
Якщо звичайну функцію викликати без об’єкта, у нестрогому режимі її this у браузері буде глобальним об’єктом:
function showThis() {
return this;
}
console.log(showThis() === globalThis); // trueТакий виклик називається простим викликом функції:
showThis();У ньому немає об’єкта перед крапкою:
showThis(); // простий виклик
user.showThis(); // виклик як методу об'єктаУ старому нестрогому режимі JavaScript підставляє глобальний об’єкт для this у звичайній функції.
Суворий режим, або strict mode, вмикається директивою "use strict":
"use strict";Директива має бути на початку скрипту або на початку тіла функції:
"use strict";
function calculate() {
// Код функції виконується у суворому режимі
}У суворому режимі звичайна функція, викликана без об’єкта, отримує this, що дорівнює undefined.
"use strict";
function showThis() {
return this;
}
console.log(showThis()); // undefinedЦе відрізняється від нестрогого режиму:
function showThisSloppy() {
return this;
}
function showThisStrict() {
"use strict";
return this;
}
console.log(showThisSloppy() === globalThis); // true у браузері
console.log(showThisStrict()); // undefinedStrict mode не змінює синтаксис виклику функції. Змінюється лише результат, який отримує звичайна функція як this.
Важливо не плутати this у глобальному коді з this усередині функції.
"use strict";
console.log(this === globalThis); // true у звичайному браузерному скрипті
function showThis() {
return this;
}
console.log(showThis()); // undefinedУ браузерному звичайному скрипті:
глобальний this як і раніше вказує на глобальний об’єкт;
this у звичайній функції під час простого виклику дорівнює undefined.
Тобто "use strict" не перетворює глобальний this на undefined.
Наведений приклад можна запустити в консолі браузера або вставити у звичайний JavaScript-файл, підключений через <script>.
console.log("Глобальний код");
console.log(this === globalThis); // true
function sloppyFunction() {
return this;
}
function strictFunction() {
"use strict";
return this;
}
console.log(sloppyFunction() === globalThis); // true
console.log(strictFunction()); // undefined
const user = {
name: "Олена",
showThis() {
return this;
}
};
console.log(user.showThis() === user); // trueОстанній приклад показує, що метод отримує this від об’єкта, перед яким стоїть крапка.
thisРозглянемо одну функцію та різні способи її виклику:
"use strict";
function showThis() {
return this;
}
const user = {
name: "Олена",
showThis
};
console.log(showThis()); // undefined
console.log(user.showThis()); // об'єкт user
console.log(showThis.call(user)); // об'єкт userРезультати:
showThis() — простий виклик, тому в strict mode this дорівнює undefined.
user.showThis() — виклик як методу, тому this дорівнює user.
showThis.call(user) — метод call явно передає user як this.
Це підтверджує правило: для звичайної функції важливий спосіб виклику.
JavaScript-модулі мають інше правило для верхнього рівня.
У модулі верхньорівневий this дорівнює undefined:
console.log(this); // undefinedМодулі автоматично працюють у strict mode, тому директива "use strict" у них не потрібна.
У браузері модуль можна підключити так:
<script type="module" src="main.js"></script>Файл main.js виконується як модуль, і його глобальний this не вказує на window.
Отже, потрібно розрізняти:
звичайний браузерний скрипт: глобальний this — це globalThis;
JavaScript-модуль: верхньорівневий this — undefined;
звичайна функція без strict mode: під час простого виклику this — глобальний об’єкт у браузері;
звичайна функція у strict mode: під час простого виклику this — undefined.
Значення глобального об’єкта залежить від середовища:
у браузері зазвичай використовується window;
у будь-якому сучасному середовищі стандартним універсальним ім’ям є globalThis;
у Node.js поведінка верхньорівневого this може відрізнятися залежно від типу файлу та модуля.
Тому для доступу до глобального об’єкта краще використовувати globalThis, якщо це справді потрібно:
console.log(globalThis);Проте не варто без потреби зберігати власні дані у глобальному об’єкті. Глобальні змінні можуть випадково конфліктувати між різними частинами програми.
this завжди вказує на функціюthis не вказує на функцію автоматично. У звичайній функції воно залежить від виклику:
"use strict";
function showThis() {
return this;
}
console.log(showThis()); // undefinedthisStrict mode змінює поведінку this у звичайній функції під час простого виклику, але не робить глобальний this у звичайному браузерному скрипті undefined.
"use strict";
console.log(this === globalThis); // true у звичайному браузерному скриптіОдна й та сама функція може отримати різне this:
"use strict";
function showName() {
return this.name;
}
const user = {
name: "Олена",
showName
};
console.log(user.showName()); // "Олена"
const savedFunction = user.showName;
console.log(savedFunction()); // TypeErrorУ першому випадку функція викликається як метод user. У другому функція викликається окремо, тому в strict mode this дорівнює undefined, і доступ до this.name спричиняє помилку.
Якщо приклад очікує, що глобальний this дорівнює window, він може поводитися інакше в модулі:
console.log(this === undefined); // true у модуліЗавжди враховуйте, як саме підключено файл: як звичайний скрипт чи як модуль.
| Ситуація | Значення this | |---|---| | Глобальний код у звичайному браузерному скрипті | globalThis | | Глобальний код у модулі | undefined | | Простий виклик звичайної функції без strict mode | globalThis у браузері | | Простий виклик звичайної функції у strict mode | undefined | | Виклик object.method() | object |
this визначається способом виклику звичайної функції.
У глобальному коді звичайного браузерного скрипту this вказує на globalThis.
У strict mode простий виклик звичайної функції дає this === undefined.
Strict mode не змінює глобальний this у звичайному браузерному скрипті.
JavaScript-модулі автоматично працюють у strict mode, а їхній верхньорівневий this дорівнює undefined.
Виклик object.method() передає об’єкт як this.
Для перевірки глобального об’єкта краще використовувати globalThis, а не покладатися лише на window.