Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Метод Function.prototype.bind». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`Function.prototype.bind` не викликає функцію, а повертає нову функцію, у якої назавжди закріплений контекст `this` і, за бажанням, частина аргументів.** Оригінальна функція не змінюється, а прив'язаний `this` уже не перевизначити ані через `call`, ані через `apply`, тому `bind` це основний спосіб зберегти контекст під час передачі методу в callback. ```javascript const user = { name: 'Maria' }; function greet() { console.log(`Hello, I am ${this.name}`); } const sayHi = greet.bind(user); setTimeout(sayHi, 1000); // Hello, I am Maria ``` **Ключове:** `call` і `apply` викликають одразу, `bind` створює нову функцію для виклику пізніше.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`Function.prototype.bind` повертає нову функцію з назавжди прив'язаним контекстом `this`, а не викликає функцію одразу.** Це третій із «методів керування контекстом» поряд із `call` та `apply`, і саме відкладений виклик робить його особливим. ## Теорія ### TL;DR - `bind` створює **нову функцію**, у якої `this` зафіксований назавжди. - Оригінальна функція **не змінюється**: `bind` повертає окрему копію. - Можна заздалегідь зафіксувати частину аргументів (partial application). - Функція **не виконується одразу**, її викликають пізніше вручну. - Прив'язаний `this` неможливо перевизначити через `call` або `apply`. - Виняток: виклик через `new` ігнорує прив'язаний контекст. ### Швидкий приклад ```javascript function greet() { console.log(`Привіт, я ${this.name}`); } const user = { name: 'Maria' }; const sayHi = greet.bind(user); sayHi(); // Привіт, я Maria ``` Тут `sayHi` це нова функція, у якої `this` **назавжди прив'язаний** до `user`. ### Синтаксис і що саме повертає bind ```javascript func.bind(thisArg, arg1, arg2, ...) ``` - `thisArg` це значення, яке стане `this` всередині функції під час виклику; - `arg1, arg2, ...` це аргументи, які будуть підставлені «за замовчуванням»; - повертається **нова функція**, яку можна викликати пізніше. Отже, `bind` створює нову функцію, у якої: - назавжди закріплений контекст `this`; - можна частково зафіксувати аргументи; - сама функція не виконується одразу, а повертається для виклику згодом. ### Втрата контексту в callback Найчастіше `bind` потрібен саме для того, щоб **зберегти `this`** під час передачі методу як callback. Коли метод передають за посиланням, зв'язок з об'єктом губиться: ```javascript const user = { name: 'Maria', sayHi() { console.log(`Привіт, я ${this.name}`); } }; setTimeout(user.sayHi, 1000); // this загублений -> "Привіт, я undefined" setTimeout(user.sayHi.bind(user), 1000); // правильно -> "Привіт, я Maria" ``` Те саме стосується обробників подій і колбеків у методах на кшталт `map`, `forEach`, `then`. ### Часткове застосування аргументів `bind` дозволяє «передзадати» не лише контекст, а й частину аргументів: ```javascript function introduce(city, job) { console.log(`Я ${this.name} з міста ${city}, працюю як ${job}`); } const person = { name: 'Maria' }; const introduceMaria = introduce.bind(person, 'Kyiv'); introduceMaria('Frontend-розробник'); // Я Maria з міста Kyiv, працюю як Frontend-розробник ``` Тут перший аргумент (`'Kyiv'`) зафіксовано заздалегідь, а решту передають під час виклику. Контекст при цьому потрібен не завжди, тож для чистого partial application передають `null`: ```javascript function multiply(a, b) { return a * b; } const double = multiply.bind(null, 2); console.log(double(5)); // 10 ``` `bind` створив нову функцію, де `a = 2` зафіксовано, і вона чекає тільки на другий аргумент `b`. ### Відмінність від call і apply | Метод | Що робить | Коли викликається | Як передаються аргументи | | --- | --- | --- | --- | | **call** | Викликає функцію із заданим `this` | Одразу | Через кому | | **apply** | Те саме, але аргументи масивом | Одразу | Масивом | | **bind** | Повертає нову функцію з «прив'язаним» `this` | Пізніше | Через кому | ### Особливості bind і поведінка з new 1. `bind` **не змінює оригінальну функцію**, а повертає **нову копію**. 2. «Прив'язаний» `this` змінити вже не можна, навіть через `call` або `apply`. 3. Якщо прив'язану функцію викликати як конструктор (`new`), `this` всередині неї буде **новим об'єктом**, а не прив'язаним контекстом. ```javascript function User(name) { this.name = name; } const BoundUser = User.bind({ name: 'Maria' }); const u = new BoundUser('Alice'); console.log(u.name); // Alice, контекст прив'язки ігнорується при new ``` Тобто при `new` у `bind` є особливість: пріоритет має конструктор, а не прив'язаний `this`. **Підсумок:** | Властивість | Опис | | --- | --- | | Що робить | Прив'язує контекст `this` і/або частину аргументів | | Що повертає | Нову функцію | | Коли викликається | Пізніше (вручну) | | Чи можна змінити контекст потім | Ні | | Часткове застосування | Так | | Часто використовується для | Callbacks, обробників подій, React-компонентів | ### Типові помилки - **Чекають, що `bind` викличе функцію.** Він лише повертає нову функцію; без пари дужок нічого не станеться. - **Не зберігають результат.** `user.sayHi.bind(user);` окремим рядком безглуздий: оригінал не змінюється, треба присвоїти результат. - **Намагаються перебити прив'язку через `call`.** Після `bind` контекст зафіксований, і `bound.call(other)` його не змінить. - **Прив'язують у кожному рендері.** `onClick={this.handle.bind(this)}` створює нову функцію щоразу і ламає мемоізацію; краще прив'язати один раз або використати стрілкову функцію. - **Прив'язують стрілкову функцію.** У стрілок немає власного `this`, тому `bind` на них не впливає.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.