Якщо говорити про звичайну функцію (не стрілкову), то значення контексту визначається не на момент створення функції, а на момент виклику.
Значення this визначається тим, як викликають функцію, а не тим, де її оголосили.
this і глобальна область видимості
Якщо скрипт виконується не в суворому режимі, то this посилається на об'єкт window. В суворому режимі this, в глобальній області видимості, буде undefined.
"use strict"; // Суворий чи не суворий режим
function myFunc() {
console.log(this);
}
myFunc(); // window or undefined
this і методи об'єкта
Якщо функція є методом обʼєкта, то контекст посилатиметься на сам обʼєкт в якому і міститься цей метод.
Раніше ми визначили: контекст визначається місцем виклику функції, а не її створення.
Тому, якщо створити функцію у глобальній області - вона матиме глобальний контекст (window або undefined). А якщо цю функцію присвоїти як метод якомусь обʼєкту, то якщо викликати цей метод, як частину об'єкта - контекст посилатиметься на цей обʼєкт. Далі приклад:
// Створюємо функцію у глобальній області видимості
function showContext() {
console.log(this);
}
// Виклик функції покаже контекст
showContext(); // window or undefined
// Створимо якийсь обʼєкт
const user = {
name: "Alex",
};
// Присвоїмо методу обʼєкту функцію з глобальної області видимості
user.showObjectContext = showContext;
// Контекст цієї функції вже буде обʼєкт user
user.showObjectContext(); // {name: 'Alex', showObjectContext: ƒ}
Якщо метод об'єкта передають як колбек-функцію, то контекст не зберігається. Колбек - це посилання на метод, яке присвоюється як значення параметра, що викликається без об'єкта.
// Створюємо обʼєкт з методом, в якому є посилання на мам обʼєкт
const user = {
name: "Alex",
showName() {
console.log(this.name);
},
};
// Видно, що метод працює і повідомлення виводиться
user.showName(); // Alex
// Передамо метод у функцію як колбек
function myFunc(callback) {
callback();
}
// Викличемо функцію в яку передамо метод, як колбек
myFunc(user.showName); // Помилка бо у myFunc немає властивості name
Стрілкові функції не мають власного this. На відміну від класичних функцій, змінити значення this всередині стрілкової функції після її оголошення - неможливо.
Контекст всередині стрілкової функції визначається місцем її оголошення, а не місцем виклику, і посилається на контекст батьківської функції.
Стрілкові функції ігнорують наявність суворого режиму. Якщо стрілка запам'ятала глобальний контекст, то this в ній буде містити посилання на window, незалежно від того, чи виконується скрипт в суворому режимі.
// Створюємо стрілкову функцію у глобальній області видимості
const showContext = () => {
console.log(this);
};
// Виклик функції покаже контекст
showContext(); // window
// Створимо якийсь обʼєкт
const user = {
name: "Alex",
};
// Присвоїмо методу обʼєкту стрілкову функцію з глобальної області видимості
user.showObjectContext = showContext;
// Контекст цієї функції буде все той же, бо це стрілка
user.showObjectContext(); // window
Обмежуючи стрілкові функції постійним контекстом, можна краще їх оптимізувати, на відміну від звичайних функцій, значення this яких можна змінити.