Skip to main content

Контекст функції

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

Теорія

TL;DR

  • this це посилання на об'єкт, у контексті якого зараз виконується функція.
  • Значення this залежить від способу виклику, а не від місця оголошення.
  • Звичайний виклик: глобальний об'єкт (window у браузері) або undefined у strict mode.
  • Виклик як метод obj.method(): контекстом стає obj.
  • Виклик через new: контекстом стає новий створений об'єкт.
  • call, apply, bind: контекст задається вручну.
  • Стрілкові функції власного this не мають і беруть його з зовнішнього оточення.

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

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

У браузері в нестрогому режимі:

javascript
this === window;

У Node.js усередині звичайної функції в строгому режимі:

javascript
this === undefined;

Контекст залежить від способу виклику

Як викликаємо функціюЯким буде this
Звичайний виклик func()Глобальний об'єкт (window) або undefined у strict mode
Виклик як метод obj.method()Об'єкт obj
Через newНовий створений об'єкт
Через call / apply / bindВказаний вручну об'єкт
У стрілковій функціїthis береться з зовнішнього контексту (лексично)

Звичайний виклик, тобто глобальний контекст:

javascript
function test() { console.log(this); } test(); // window (або undefined у strict mode)

Виклик як метод об'єкта:

javascript
const user = { name: "Alice", sayHi() { console.log(this.name); }, }; user.sayHi(); // "Alice"

Тут this посилається на об'єкт user, бо функцію викликано саме як user.sayHi().

Втрата контексту

javascript
const user = { name: "Alice", sayHi() { console.log(this.name); }, }; const hi = user.sayHi; hi(); // undefined, this втрачено

Чому так:

  • Ми передали посилання на функцію, але не сам об'єкт.
  • Виклик hi() це звичайний виклик, без контексту user.

Виправлення через bind:

javascript
const hi = user.sayHi.bind(user); hi(); // "Alice"

Та сама пастка трапляється, коли метод передають як колбек: setTimeout(user.sayHi, 100) або button.addEventListener("click", user.sayHi).

Контекст при виклику через new

javascript
function User(name) { this.name = name; } const u = new User("Alice"); console.log(u.name); // "Alice"

Тут this вказує на новий створений об'єкт (u). Оператор new створює порожній об'єкт, робить його контекстом виклику і повертає його, якщо функція явно не повернула інший об'єкт.

call, apply і bind

javascript
function greet() { console.log(this.name); } const user = { name: "Maria" }; greet.call(user); // "Maria" greet.apply(user); // "Maria" const boundGreet = greet.bind(user); boundGreet(); // "Maria"
МетодЩо робить
call(thisArg, arg1, arg2, ...)викликає функцію з указаним this і аргументами через кому
apply(thisArg, [args])те саме, але аргументи передаються масивом
bind(thisArg)повертає нову функцію із зафіксованим this, не викликаючи її одразу

Стрілкові функції та підсумок

javascript
const obj = { name: "Alice", arrow: () => console.log(this.name), regular() { console.log(this.name); }, }; obj.arrow(); // undefined, this це зовнішній контекст, не obj obj.regular(); // "Alice"

Важливо:

  • Стрілкові функції не мають власного this.
  • Вони «беруть» this із зовнішнього лексичного оточення, тобто звідти, де їх створено.
  • Через це call, apply і bind не змінюють this у стрілковій функції.

Підсумкова таблиця:

СитуаціяЯким буде this
Звичайний викликwindow або undefined
Метод об'єктаСам об'єкт
newНовий екземпляр
call, apply, bindВказаний вручну об'єкт
Стрілкова функціяУспадковує this ззовні

Контекст функції це «власник виклику»: хто викликає функцію, той і стає this.

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

  • Вважати, що this визначається місцем оголошення. Ні, він визначається місцем і способом виклику.
  • Передавати метод як колбек без прив'язки. setTimeout(user.sayHi, 100) втрачає контекст. Треба user.sayHi.bind(user) або стрілкова обгортка () => user.sayHi().
  • Робити метод об'єкта стрілковою функцією. Тоді this вказує не на об'єкт, а на зовнішнє оточення, і this.name дасть undefined.
  • Плутати call і apply. call приймає аргументи через кому, apply приймає масив.
  • Очікувати, що bind можна перевизначити. Прив'язану функцію не можна перепривʼязати повторним bind або call: перша прив'язка перемагає.
  • Забувати про strict mode. У модулях і класах код завжди строгий, тому в звичайному виклику там буде undefined, а не window.

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

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

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