Пошук уроків, статей та іншого контенту
Функції, які приймають або повертають інші функції — основа для array-методів, подій та асинхронного коду.
Функція вищого порядку — це функція, яка приймає іншу функцію як аргумент, повертає функцію, або і те, і інше. Це прямий наслідок того, що функції в JavaScript — звичайні значення (перший урок цього модуля).
Колбек (callback) — це функція, передана як аргумент, яку викликають усередині іншої функції в потрібний момент:
function processData(data, onComplete) {
const result = data.map((x) => x * 2);
onComplete(result); // виклик колбека, коли робота завершена
}
processData([1, 2, 3], (result) => {
console.log("Готово:", result); // "Готово: [2, 4, 6]"
});setTimeout(() => {
console.log("Минуло 2 секунди");
}, 2000);Тут setTimeout — функція вищого порядку: вона приймає колбек і викликає його самостійно, коли настане потрібний момент (детальніше про це в модулі «Асинхронний JavaScript»).
Другий напрямок — функція, яка створює й повертає нову, налаштовану функцію. Це той самий патерн, що ми бачили із замиканнями:
function multiplyBy(factor) {
return function (number) {
return number * factor;
};
}
const double = multiplyBy(2);
const triple = multiplyBy(3);
double(5); // 10
triple(5); // 15Debounce — функція вищого порядку, що відкладає виклик, поки не мине пауза без нових викликів. Класичне застосування — пошук під час набору тексту, щоб не робити запит на кожну літеру:
function debounce(fn, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(...args), delay);
};
}
const debouncedSearch = debounce((query) => {
console.log("Пошук:", query);
}, 300);
// швидкі виклики поспіль скасовують попередній таймер —
// реальний пошук піде лише через 300мс після ОСТАННЬОГО виклику
debouncedSearch("j");
debouncedSearch("ja");
debouncedSearch("java"); // лише цей виклик зрештою спрацюєdebounce поєднує все з цього модуля: замикання (зберігає timeoutId між викликами), rest-параметри (...args) і функцію, що повертає функцію.
map, filter та reduce (детально в наступному модулі) — усі приймають колбек як аргумент, тобто самі є функціями вищого порядку:
[1, 2, 3].map((x) => x * 2); // [2, 4, 6]Виклик колбека одразу замість передачі посилання на функцію: onComplete() замість onComplete у сигнатурі виклику.
Забутий clearTimeout у debounce-подібних функціях — накопичуються зайві відкладені виклики.
Плутанина між функцією, що повертає значення, і функцією, що повертає іншу функцію.
Функції вищого порядку — фундамент ідіоматичного JavaScript: колбеки керують тим, коли й з якими даними виконається код, а функції, що повертають функції, дозволяють створювати налаштовані, спеціалізовані версії загальної поведінки. Ці патерни готують ґрунт для методів масивів (наступний модуль) і асинхронного коду (модуль 8).
Спробуйте самостійно
Напишіть функцію вищого порядку once(fn), яка повертає нову функцію, що викликає fn не більше одного разу — усі наступні виклики повертають результат першого виклику, не викликаючи fn повторно. Підказка: знадобиться замикання зі змінною-прапорцем.