Розуміння методів call
, apply
та bind
у JavaScript
Методи JavaScript call
, apply
та bind
дозволяють явно встановлювати контекст this
для функції. Ці методи є основою для розуміння динамічної поведінки this
в JavaScript і часто зустрічаються на технічних співбесідах. Давайте розглянемо їх функціональність та те, як вони працюють внутрішньо.
1. call
Метод call
дозволяє викликати функцію з вказаним значенням this
. Першим аргументом є об'єкт, який буде використовуватись як this
, а далі передаються аргументи, які будуть передані функції.
function greet(name) {
console.log(`Hello, ${name}!`);
}
greet.call(null, 'Alice'); // Виведе: Hello, Alice!
У прикладі вище ми використовуємо call
для виклику функції greet
і передаємо аргумент 'Alice'
.
2. apply
Метод apply
є дуже схожим на call
, але замість того, щоб передавати аргументи окремо, вони передаються як масив. Це зручно, коли кількість аргументів функції невідома або коли передача аргументів в масиві є більш зручною.
function greet(name, age) {
console.log(`Hello, ${name}! You are ${age} years old.`);
}
greet.apply(null, ['Bob', 25]); // Виведе: Hello, Bob! You are 25 years old.
Як бачите, ми передаємо аргументи через масив у методі apply
.
3. bind
Метод bind
створює нову функцію, де контекст this
буде зафіксований на вказаному значенні. На відміну від call
та apply
, метод bind
не викликає функцію негайно, а повертає нову функцію, яку можна викликати пізніше.
function greet(name) {
console.log(`Hello, ${name}!`);
}
const greetAlice = greet.bind(null, 'Alice');
greetAlice(); // Виведе: Hello, Alice!
У цьому прикладі ми використовуємо bind
для створення нової функції, яка завжди буде вітати 'Alice'.
Висновок
Методи call
, apply
та bind
є потужними інструментами для роботи з контекстом функцій в JavaScript. Вони дозволяють налаштовувати поведінку this
для кожного конкретного виклику функції. Розуміння їх відмінностей та того, коли їх використовувати, є важливим аспектом для кожного розробника.
call
Мета:
Виконує функцію з вказаним контекстом this
та аргументами, які передаються окремо.
Як це працює внутрішньо:
Function.prototype.myCall = function (context, ...args) {
context = context || globalThis; // За замовчуванням використовуємо глобальний об'єкт, якщо context = null або undefined
const uniqueKey = Symbol(); // Уникаємо конфліктів з іменами властивостей
context[uniqueKey] = this; // Тимчасово присвоюємо функцію контексту
const result = context[uniqueKey](...args); // Викликаємо функцію з аргументами, що передаються через spread
delete context[uniqueKey]; // Очищаємо тимчасову властивість
return result;
};
Приклад використання:
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const user = { name: "Alice" };
greet.myCall(user, "Hello"); // Виведе: Hello, Alice
2.
apply
Мета:
Виконує функцію з вказаним контекстом this
та аргументами, переданими у вигляді масиву.
Як це працює внутрішньо:
Function.prototype.myApply = function (context, args) {
context = context || globalThis;
const uniqueKey = Symbol();
context[uniqueKey] = this;
const result = args ? context[uniqueKey](...args) : context[uniqueKey]();
delete context[uniqueKey];
return result;
};
Приклад використання:
function sum(a, b) {
return a + b;
}
console.log(sum.myApply(null, [1, 2])); // Виведе: 3
3. bind
Мета:
Створює нову функцію з вказаним контекстом this
та необов'язковими заздалегідь переданими аргументами.
Функція не виконується негайно.
Як це працює внутрішньо:
Function.prototype.myBind = function (context, ...args) {
const fn = this; // Зберігаємо посилання на оригінальну функцію
return function (...innerArgs) {
return fn.apply(context, [...args, ...innerArgs]); // Комбінуємо аргументи
};
};
Приклад використання:
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
const user = { name: "Alice" };
const boundGreet = greet.myBind(user, "Hello");
boundGreet("!"); // Виведе: Hello, Alice!
Ключові відмінності між call
, apply
та bind
Виконання:
call
: Негайне.
apply
: Негайне.
bind
: Затримане (повертає нову функцію).
Аргументи:
call
: Передаються окремо.
apply
: Передаються як масив.
bind
: Передаються при зв'язуванні, додаткові аргументи — під час виклику.
Повернуте значення:
call
: Результат викликаної функції.
apply
: Результат викликаної функції.
bind
: Нова зв'язана функція.
Інсайти для співбесід
Розуміння цих концепцій допоможе вам вирішити складніші питання на співбесідах, такі як:
- Як динамічно визначається
this
у JavaScript. - Як
bind
дає можливість створювати замикання (closures) та працювати з прослуховувачами подій (Event Listeners). - Як
call
таapply
спрощують використання методів з інших об'єктів.
Освоївши методи call
, apply
та bind
, ви краще зрозумієте механізм this
в JavaScript та його гнучкість у роботі з контекстом.
Це необхідні інструменти для написання чистого, модульного та багаторазового коду.
Перекладено з: Call, Bind and Apply : Pollyfills and How it works