Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Передавання callback в іншу функцію». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Callback передають просто як аргумент під час виклику іншої функції, бо в JavaScript функції є значеннями (first-class citizens), а всередині приймальної функції його викликають за іменем параметра.** Передавати треба посилання на функцію, без дужок: `doSomething(afterDone)`, а не `doSomething(afterDone())`. ```javascript function doSomething(callback) { console.log('Doing something...'); callback(); // call the callback we were given } function afterDone() { console.log('Done!'); } doSomething(afterDone); // Doing something... / Done! ``` **Ключове:** вкажіть функцію як аргумент при виклику, а всередині приймальної функції викличте її за іменем параметра тоді, коли потрібно.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Щоб передати callback, вкажіть функцію як звичайний аргумент під час виклику іншої функції, а всередині приймальної функції викличте її за іменем параметра.** Це можливо тому, що в JavaScript функції є значеннями (first-class citizens): їх можна присвоювати змінним, класти в масиви і передавати як аргументи. ## Теорія ### TL;DR - Callback передається як звичайний аргумент: `doSomething(afterDone)`. - Передавайте посилання на функцію, без дужок. Дужки означають виклик і передадуть результат, часто `undefined`. - Усередині приймальної функції колбек викликають за іменем параметра: `callback()`. - Можна передати іменовану функцію, анонімну функцію або стрілкову функцію прямо на місці виклику. - Приймальній функції байдуже, що саме робить callback: вона отримує поведінку ззовні. ### Швидкий приклад ```javascript function doSomething(callback) { console.log('Doing something...'); callback(); // call the callback we were given } function afterDone() { console.log('Done!'); } doSomething(afterDone); ``` Вивід: ```text Doing something... Done! ``` ### Три способи передати callback Форма запису різна, суть однакова: у параметр `callback` потрапляє функція. ```javascript // 1. Іменована функція, передаємо посилання на неї function afterDone() { console.log('Done!'); } doSomething(afterDone); // 2. Анонімна функція прямо в аргументі doSomething(function () { console.log('Done!'); }); // 3. Стрілкова функція, найкоротший запис doSomething(() => { console.log('Done!'); }); ``` | Спосіб | Коли зручний | | --- | --- | | Іменована функція | Логіку перевикористовують у кількох місцях, її легко протестувати окремо | | Анонімна `function` | Потрібен власний `this` або `arguments` усередині колбека | | Стрілкова функція | Короткий одноразовий обробник, `this` береться із зовнішньої області | ### Передавання аргументів у callback Приймальна функція сама вирішує, з якими аргументами викликати колбек. Викликач лише описує, що робити з цими значеннями. ```javascript function doSomething(callback) { const result = 42; callback(result); // pass data into the callback } doSomething(value => { console.log('Got', value); // Got 42 }); ``` Якщо треба «зафіксувати» власні аргументи заздалегідь, загорніть виклик у стрілкову функцію або застосуйте `bind`. ```javascript function greet(name) { console.log('Hello, ' + name); } doSomething(() => greet('Maria')); // wrapper keeps the argument doSomething(greet.bind(null, 'Oleh')); // the same via bind ``` ### Виклик замість передавання: головна пастка `afterDone` це функція, `afterDone()` це вже її результат. Дужки в аргументі виконують функцію негайно, і приймальна функція отримає не поведінку, а значення, яке та повернула. ```javascript doSomething(afterDone); // correct: pass the function itself doSomething(afterDone()); // wrong: runs now and passes undefined ``` Той самий принцип працює для будь-якого API, що приймає колбек: `setTimeout(fn, 100)`, `addEventListener('click', fn)`, `array.map(fn)`. ### Захист від відсутнього колбека Якщо параметр необов'язковий, перевірте його перед викликом або дайте значення за замовчуванням, інакше отримаєте `TypeError: callback is not a function`. ```javascript function doSomething(callback = () => {}) { console.log('Doing something...'); callback(); } doSomething(); // works even without an argument ``` ### Типові помилки - Передавати `afterDone()` замість `afterDone`: функція виконається одразу, а в параметр потрапить `undefined`. - Ставити дужки в `setTimeout(sayHi(), 100)` і дивуватися, що таймер нічого не робить. - Викликати колбек, не перевіривши, що його справді передали, і отримувати `TypeError`. - Передавати метод об'єкта напряму, `obj.handler`, і втрачати `this`. Рятує стрілкова обгортка або `bind`. - Очікувати, що значення з асинхронного колбека буде доступне одразу після виклику функції: воно з'явиться лише тоді, коли колбек справді виконається.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.