Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «call проти apply». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`call` і `apply` роблять абсолютно одне й те саме: викликають функцію негайно з явно заданим `this`, а різниця між ними лише у формі аргументів.** `call` приймає аргументи переліком через кому, а `apply` приймає їх одним масивом, тому `call` зручний, коли аргументи відомі наперед, а `apply` коли вони вже лежать у масиві. ```javascript func.call(thisArg, arg1, arg2, arg3); // через кому func.apply(thisArg, [arg1, arg2, arg3]); // масивом ``` **Ключове:** однакова поведінка, різна форма аргументів; у сучасному коді обидва часто замінює spread `func(...args)`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`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. ### Підсумкова таблиця | Властивість | `call` | `apply` | | --- | --- | --- | | Контекст (`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` це питання зручності, а не швидкості.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.