Функции высшего порядка в JavaScript

Функция высшего порядка - это функция, которая работает с другими функциями.

Такую функцию можно узнать по одному из двух признаков:

1. Она принимает другую функцию как аргумент.

2. Она возвращает другую функцию как результат.

function runAction(action) {
  action();
}

function sayHello() {
  console.log('Привет!');
}

runAction(sayHello);

В этом примере runAction() - функция высшего порядка, потому что она принимает другую функцию.

Что такое функция высшего порядка

В JavaScript функции можно передавать как обычные значения: записывать в переменные, передавать в другие функции и возвращать из функций.

let showMessage = function () {
  console.log('Сообщение');
};

showMessage();

Благодаря этому можно писать функции, которые не просто работают с числами или строками, а управляют другими функциями.

Именно такие функции называют функциями высшего порядка.

Функция принимает функцию

Самый частый вариант - функция принимает другую функцию как аргумент.

function calculate(a, b, operation) {
  return operation(a, b);
}

function sum(a, b) {
  return a + b;
}

function multiply(a, b) {
  return a * b;
}

console.log(calculate(3, 4, sum));
console.log(calculate(3, 4, multiply));

Результат:

7
12

calculate() не решает сама, какую операцию выполнить. Она получает функцию operation и вызывает ее.

Такой подход полезен, когда основная логика одна, а отдельное действие может меняться.

Связь с callback-функциями

Callback-функция - это функция, которую передали в другую функцию.

Функция, которая принимает callback, является функцией высшего порядка.

function repeat(count, callback) {
  for (let i = 1; i <= count; i++) {
    callback(i);
  }
}

function showNumber(number) {
  console.log(number);
}

repeat(3, showNumber);

Результат:

1
2
3

showNumber - callback-функция.

repeat - функция высшего порядка, потому что она принимает callback.

Функция возвращает функцию

Функция высшего порядка может не только принимать функцию, но и возвращать новую функцию.

function createMultiplier(multiplier) {
  return function (number) {
    return number * multiplier;
  };
}

let double = createMultiplier(2);
let triple = createMultiplier(3);

console.log(double(5));
console.log(triple(5));

Результат:

10
15

createMultiplier() возвращает функцию. Поэтому это тоже функция высшего порядка.

Такая запись полезна, когда нужно создать похожие функции с разными настройками. Подробно этот механизм связан с замыканиями, их разберем отдельно.

Методы массивов

Многие методы массивов в JavaScript являются функциями высшего порядка.

Например, map() принимает функцию и вызывает ее для каждого элемента массива.

let numbers = [1, 2, 3];

let doubled = numbers.map(function (number) {
  return number * 2;
});

console.log(doubled);

Результат:

[2, 4, 6]

map() управляет перебором массива, а переданная функция описывает, что сделать с каждым элементом.

По такому же принципу работают filter(), forEach(), some(), every() и другие методы.

Когда это полезно

Функции высшего порядка помогают не дублировать похожий код.

function checkNumbers(numbers, condition) {
  let result = [];

  for (let number of numbers) {
    if (condition(number)) {
      result.push(number);
    }
  }

  return result;
}

function isEven(number) {
  return number % 2 === 0;
}

function isPositive(number) {
  return number > 0;
}

let numbers = [-2, -1, 0, 1, 2, 3];

console.log(checkNumbers(numbers, isEven));
console.log(checkNumbers(numbers, isPositive));

Результат:

[-2, 0, 2]
[1, 2, 3]

Функция checkNumbers() один раз описывает общий проход по массиву. Условие отбора передается отдельно.

Итого

1. Функция высшего порядка работает с другими функциями.

2. Она может принимать функцию как аргумент.

3. Она может возвращать функцию как результат.

4. Функция, которая принимает callback, является функцией высшего порядка.

5. Методы массивов вроде map(), filter() и forEach() - частые примеры функций высшего порядка.