Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Метод Function.prototype.apply». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`Function.prototype.apply` викликає функцію негайно з явно заданим контекстом `this`, але аргументи передає одним масивом (або масивоподібним об'єктом), а не через кому.** Це найближчий родич `call`: різниця лише у формі аргументів, тому `apply` зручний, коли аргументи вже зібрані в масив, наприклад `Math.max.apply(null, nums)`. ```javascript function sum(a, b, c) { return a + b + c; } console.log(sum.apply(null, [1, 2, 3])); // 6 ``` **Ключове:** `apply` це `call` з аргументами у вигляді масиву; сучасна альтернатива це spread `func(...args)`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`Function.prototype.apply` викликає функцію з явно вказаним контекстом (`this`), передаючи їй аргументи у вигляді масиву.** Це «близький брат» методу `call`, і відрізняються вони тільки способом передачі аргументів. ## Теорія ### TL;DR - `apply` викликає функцію **одразу** і дозволяє вручну задати `this`. - Аргументи передаються **масивом** або масивоподібним об'єктом, а не через кому. - `call` робить те саме, але аргументи йдуть переліком через кому. - `bind` нічого не викликає: він лише повертає нову функцію з «прив'язаним» `this`. - Класичні застосування: `Math.max.apply(null, nums)` і «позичання» методів масиву для `arguments`. - Сучасна заміна в багатьох випадках: spread-синтаксис `func(...args)`. ### Швидкий приклад ```javascript function sum(a, b, c) { return a + b + c; } const numbers = [1, 2, 3]; // аргументи вже в масиві, тому apply підходить ідеально console.log(sum.apply(null, numbers)); // 6 ``` ### Синтаксис ```javascript func.apply(thisArg, [argsArray]) ``` - `thisArg` це об'єкт, який стане `this` всередині функції; - `argsArray` це масив (або масивоподібний об'єкт) з аргументами. Базове використання з явним контекстом: ```javascript function greet(city, job) { console.log(`Я ${this.name} з міста ${city}, працюю як ${job}`); } const user = { name: 'Maria' }; greet.apply(user, ['Kyiv', 'Frontend-розробник']); // Я Maria з міста Kyiv, працюю як Frontend-розробник ``` Те саме через `call`: ```javascript greet.call(user, 'Kyiv', 'Frontend-розробник'); ``` Різниця тільки **у способі передачі аргументів**: - `call` -> через кому, - `apply` -> масивом. ### Робота з масивоподібними об'єктами `apply` часто застосовують, коли аргументи вже зберігаються в масиві або схожій структурі (`arguments`, `NodeList` тощо). Це дозволяє «позичити» метод масиву для об'єкта, у якого власних методів масиву немає: ```javascript function logArgs() { console.log(arguments); // перетворюємо arguments на масив за допомогою Array.prototype.slice const arr = Array.prototype.slice.apply(arguments); console.log(arr); } logArgs(1, 2, 3, 4); // arguments -> [1, 2, 3, 4] ``` Тут `apply` дає змогу викликати метод масиву (`slice`) на об'єкті `arguments`, який масивом не є, але має `length` і числові індекси. ### Math.max і Math.min через apply Методи `Math.max` і `Math.min` **не приймають масив**, лише перелік чисел. `apply` елегантно вирішує цю проблему: ```javascript const nums = [10, 20, 5, 40]; console.log(Math.max.apply(null, nums)); // 40 console.log(Math.min.apply(null, nums)); // 5 ``` Аналог на ES6: ```javascript Math.max(...nums); // сучасний spread-синтаксис ``` ### apply проти call і bind | Метод | Що робить | Як передаються аргументи | Коли викликається | | --- | --- | --- | --- | | **call** | Викликає функцію із заданим `this` | Через кому | Одразу | | **apply** | Викликає функцію із заданим `this` | У вигляді масиву | Одразу | | **bind** | Створює нову функцію з «прив'язаним» `this` | Через кому | Пізніше (під час виклику) | **Підсумок по `apply`:** | Властивість | Опис | | --- | --- | | Призначення | Викликати функцію із заданим `this` | | Спосіб передачі аргументів | Масив або масивоподібний об'єкт | | Контекст виконання | Глобальний або заданий вручну | | Коли використовувати | Коли аргументи вже зібрані в масив | | Сучасна альтернатива | `func(...args)` (spread-синтаксис) | ### Особливості thisArg Якщо `thisArg` дорівнює `null` або `undefined`, то: - у **строгому режимі** (`'use strict'`) -> `this = undefined`; - у **нестрогому** -> `this = window` (або `global` у Node.js). ```javascript function showThis() { console.log(this); } showThis.apply(null); // window (у нестрогому режимі) ``` Саме тому в прикладах на кшталт `Math.max.apply(null, nums)` перший аргумент безпечно ставлять `null`: контекст цим функціям не потрібен. ### Типові помилки - **Плутають `call` і `apply`.** `apply` очікує **один** масив, тому `sum.apply(null, 1, 2, 3)` не спрацює, а `sum.call(null, [1, 2, 3])` передасть масив як перший аргумент. - **Думають, що `apply` повертає нову функцію.** Її повертає `bind`; `apply` виконує функцію негайно і повертає її результат. - **Розраховують на глобальний `this` у строгому режимі.** У модулях і класах код виконується в строгому режимі, тому `this` при `null` залишиться `undefined`. - **Передають у `apply` дуже великий масив.** Кожен елемент стає окремим аргументом, тож на масивах у сотні тисяч елементів можна отримати `RangeError: Maximum call stack size exceeded`. - **Намагаються створити об'єкт через `apply`.** `apply` не працює з `new`: для виклику конструктора з масивом аргументів потрібні `Reflect.construct(Ctor, args)` або `new Ctor(...args)`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.