Skip to main content

call проти apply

call і apply викликають функцію із явно вказаним контекстом this, і відрізняються тільки способом передачі аргументів: call бере їх через кому, а apply одним масивом. Результат виклику, момент виклику і поведінка this у них ідентичні.

Теорія

TL;DR

  • Обидва методи викликають функцію одразу і повертають її результат.
  • Перший аргумент в обох це thisArg, тобто контекст виклику.
  • call -> аргументи через кому: func.call(thisArg, arg1, arg2, arg3).
  • apply -> аргументи масивом: func.apply(thisArg, [arg1, arg2, arg3]).
  • Аргументи відомі наперед -> call; аргументи вже в масиві -> apply.
  • У сучасному JS обидва часто замінює spread-оператор: func(...args).

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

МетодЯк передаються аргументиПриклад виклику
callперелічуються через комуfunc.call(thisArg, arg1, arg2, arg3)
applyпередаються у вигляді масивуfunc.apply(thisArg, [arg1, arg2, arg3])
javascript
function greet(city, job) { console.log(`Я ${this.name} з міста ${city}, працюю як ${job}`); } const user = { name: 'Maria' }; // call: аргументи через кому greet.call(user, 'Kyiv', 'Frontend-розробник'); // apply: аргументи масивом greet.apply(user, ['Kyiv', 'Frontend-розробник']);

Обидва виклики виведуть одне й те саме:

Я Maria з міста Kyiv, працюю як Frontend-розробник

Коли використовувати який

СценарійКраще використати
Аргументи відомі заздалегідьcall
Аргументи вже знаходяться в масивіapply

Приклад із масивом аргументів:

javascript
function sum(a, b, c) { return a + b + c; } const nums = [1, 2, 3]; // без apply довелося б розкладати масив вручну console.log(sum.call(null, nums[0], nums[1], nums[2])); // з apply просто передаємо масив console.log(sum.apply(null, nums)); // 6

Що довший масив, то помітніша перевага apply: розкладати десять елементів вручну через call неможливо, якщо довжина масиву заздалегідь невідома.

Сучасний аналог зі spread

У сучасних версіях JavaScript (ES6+) apply часто замінюють оператором spread:

javascript
const nums = [1, 2, 3]; console.log(sum(...nums)); // той самий результат, що й sum.apply(null, nums)

Spread читається простіше і не вимагає штучного null як контексту. apply залишається доречним тоді, коли this справді треба підмінити, наприклад fn.apply(ctx, args), або в старому коді без підтримки ES6.

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

Властивістьcallapply
Контекст (this)Явно вказується першим аргументомТак само
Передача аргументівЧерез комуМасивом
Що повертаєРезультат функціїРезультат функції
Чи викликає одразуТакТак
Сучасна альтернативаSpread: func(...args)Spread: func(...args)

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

  • Передають масив у call. sum.call(null, [1, 2, 3]) віддасть масив як перший параметр a, і результат буде "1,2,3undefinedundefined", а не 6.
  • Перелічують аргументи в apply. sum.apply(null, 1, 2, 3) ігнорує все після другого параметра: apply читає лише один масив.
  • Плутають їх із bind. call і apply викликають функцію негайно, а bind тільки повертає нову функцію, яку треба викликати окремо.
  • Забувають про thisArg. Перший аргумент обов'язковий за позицією: якщо контекст не потрібен, передають null, а не пропускають його.
  • Чекають на різну продуктивність. Різниці по суті немає, вибір між call і apply це питання зручності, а не швидкості.

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

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

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