Функции высшего порядка
Функция высшего порядка принимает функцию как аргумент или возвращает функцию.
Принимают функцию
Методы массивов:
[1, 2, 3].map((x) => x * 2);
[1, 2, 3].filter((x) => x > 1);
[1, 2, 3].reduce((acc, x) => acc + x, 0);
setTimeout, addEventListener:
setTimeout(() => console.log('позже'), 1000);
element.addEventListener('click', handler);
Возвращают функцию
function multiplier(factor) {
return (n) => n * factor;
}
const double = multiplier(2);
double(5); // 10
Оба
function compose(...fns) {
return (x) => fns.reduceRight((acc, fn) => fn(acc), x);
}
forEach
[1, 2, 3].forEach((item, index, array) => {
console.log(item, index);
});
Нельзя прервать. Возвращает undefined.
map
const doubled = [1, 2, 3].map((x) => x * 2); // [2, 4, 6]
Длина результата = длина исходного.
filter
const evens = [1, 2, 3, 4].filter((x) => x % 2 === 0); // [2, 4]
reduce
const sum = [1, 2, 3].reduce((acc, x) => acc + x, 0); // 6
С объектом:
const counted = ['a', 'b', 'a'].reduce((acc, x) => {
acc[x] = (acc[x] ?? 0) + 1;
return acc;
}, {});
some и every
[1, 2, 3].some((x) => x > 2); // true
[1, 2, 3].every((x) => x > 0); // true
find и findIndex
[1, 2, 3].find((x) => x > 1); // 2
[1, 2, 3].findIndex((x) => x > 1); // 1
flatMap
[1, 2].flatMap((x) => [x, x * 2]); // [1, 2, 2, 4]
Эквивалент map + flat.
sort со сравнением
[3, 1, 2].sort((a, b) => a - b); // [1, 2, 3]
Паттерн: pipe
const pipe = (...fns) => (x) => fns.reduce((acc, fn) => fn(acc), x);
const process = pipe(
(x) => x * 2,
(x) => x + 1,
(x) => x.toString(),
);
process(5); // '11'
Паттерн: compose
То же, но справа налево:
const compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x);
Паттерн: debounce
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
const search = debounce((query) => console.log(query), 500);
Паттерн: throttle
function throttle(fn, delay) {
let last = 0;
return (...args) => {
const now = Date.now();
if (now - last >= delay) {
last = now;
fn(...args);
}
};
}
Паттерн: once
function once(fn) {
let called = false;
let result;
return (...args) => {
if (!called) {
called = true;
result = fn(...args);
}
return result;
};
}
Паттерн: retry
async function retry(fn, attempts = 3, delay = 1000) {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (e) {
if (i === attempts - 1) throw e;
await new Promise((r) => setTimeout(r, delay));
}
}
}
Практика: массив → словарь
function indexBy(items, key) {
return items.reduce((acc, item) => {
acc[item[key]] = item;
return acc;
}, {});
}
Итоги
- Функции высшего порядка принимают или возвращают функции
- Методы массивов — базовый пример
pipe,compose— композицияdebounce,throttle,once— утилиты- Основа функционального стиля