Skip to main content

Функція вищого порядку

Функція вищого порядку (higher-order function), це функція, яка приймає іншу функцію як аргумент або повертає функцію як результат. Достатньо однієї з цих двох властивостей, щоб функцію вважали функцією вищого порядку.

Теорія

TL;DR

  • Функція вищого порядку приймає функцію як аргумент або повертає функцію.
  • Це можливо тому, що в JavaScript функції є об'єктами першого класу.
  • Функцію можна передати як значення, зберегти у змінній, повернути з іншої функції.
  • Вбудовані приклади: map, filter, reduce, setTimeout, addEventListener.
  • Дають гнучкість, перевикористання логіки та абстракції над колекціями і подіями.
  • Це основний інструмент функціонального програмування.

Швидкий приклад

javascript
function repeat(n, action) { for (let i = 0; i < n; i++) { action(i); } } repeat(3, console.log); // 0 // 1 // 2

repeat, це функція вищого порядку, бо вона викликає передану функцію action.

Функції як об'єкти першого класу

У JavaScript функції є об'єктами першого класу (first-class citizens), а отже їх можна:

  • передавати як значення,
  • зберігати у змінних,
  • повертати з інших функцій.

Функції, які використовують інші функції у такий спосіб, і називають функціями вищого порядку.

javascript
const greet = function (name) { // зберігаємо у змінній return `Hello, ${name}`; }; const actions = [greet]; // кладемо в масив console.log(actions[0]('Maria')); // Hello, Maria

Приймає функцію як аргумент

javascript
function repeat(n, action) { for (let i = 0; i < n; i++) { action(i); } } repeat(3, console.log); // 0 // 1 // 2

Функція, яку передають усередину, зазвичай називають колбеком (callback). Сама repeat нічого не знає про те, що робитиме action: вона відповідає лише за повторення. Саме цей поділ відповідальності і робить код гнучким.

Повертає нову функцію

javascript
function multiplier(factor) { return function (num) { return num * factor; }; } const double = multiplier(2); console.log(double(5)); // 10

multiplier, це функція вищого порядку, бо повертає іншу функцію. Повернена функція пам'ятає factor завдяки closure (замиканню), тому double назавжди множить на 2, а multiplier(10) дасть незалежну функцію, що множить на 10.

Вбудовані приклади в JavaScript

Багато методів масивів, це функції вищого порядку:

javascript
[1, 2, 3].map(x => x * 2); // приймає функцію [1, 2, 3].filter(x => x > 1); // приймає функцію [1, 2, 3].reduce((a, b) => a + b, 0); // приймає функцію

Те саме стосується браузерних і платформних API: setTimeout(fn, 0), addEventListener('click', fn), promise.then(fn), arr.sort(compareFn). Усі вони приймають функцію і вирішують, коли і з якими аргументами її викликати.

Навіщо вони потрібні

  • Підвищують гнучкість і перевикористовність коду: одна узагальнена функція обслуговує багато сценаріїв.
  • Дають змогу будувати абстракції, наприклад обробку колекцій, подій, повторних спроб.
  • Це основний інструмент функціонального програмування.
ВластивістьОпис
Що робитьПриймає або повертає функції
Прикладиmap, filter, reduce, setTimeout, addEventListener
ПеревагиПовторне використання логіки, компактність коду
Ключова ідеяФункції, такі самі дані, як числа чи рядки

Функція вищого порядку, це функція, яка працює з іншими функціями як з даними: приймає їх як аргументи або повертає як результат.

Типові помилки

  • Викликати функцію замість того, щоб передати її. setTimeout(sayHi(), 1000) передає результат виклику, а не саму функцію; правильно setTimeout(sayHi, 1000).
  • Передавати метод і губити this. element.addEventListener('click', obj.handle) втрачає контекст; потрібні obj.handle.bind(obj) або стрілкова обгортка.
  • Плутати колбек із функцією вищого порядку. Вищого порядку, це та функція, яка приймає колбек, а не сам колбек.
  • Передавати parseInt напряму в map. ['1','2','3'].map(parseInt) дасть [1, NaN, NaN], бо map передає ще й індекс, який стає системою числення.
  • Думати, що будь-яка функція з аргументом-об'єктом уже вища за порядком. Значення має бути саме функцією, а не звичайними даними.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.