Выразительный JavaScript (Хавербеке) - страница 48

>    console.log(array[i]);

>}

Но что, если нам надо делать что-то другое, нежели выводить элементы в консоль? Поскольку «делать что-то» можно представить как функцию, а функции – это просто переменные, мы можем передать это действие как аргумент:

>function forEach(array, action) {

>  for (var i = 0; i < array.length; i++)

>    action(array[i]);

>}


>forEach(["Тили", "Мили", "Трямдия"], console.log);

>// → Тили

>// → Мили

>// → Трямдия

Часто можно не передавать заранее определённую функцию в >forEach, а создавать функцию прямо на месте.

>var numbers = [1, 2, 3, 4, 5], sum = 0;

>forEach(numbers, function(number) {

>  sum += number;

>});

>console.log(sum);

>// → 15

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

Используя этот шаблон, мы можем задать имя переменной для текущего элемента массива (>number), без необходимости выбирать его из массива вручную.

Вообще, нам даже не нужно писать самим >forEach. Это стандартный метод массивов. Так как массив уже передан в качестве переменной, над которой мы работаем, >forEach принимает только один аргумент – функцию, которую нужно выполнить для каждого элемента.

Для демонстрации удобства этого подхода вернёмся к функции из предыдущей главы. Она содержит два цикла, проходящих по массивам:

>function gatherCorrelations(journal) {

>  var phis = {};

>  for (var entry = 0; entry < journal.length; entry++) {

>    var events = journal[entry].events;

>    for (var i = 0; i < events.length; i++) {

>      var event = events[i];

>      if (!(event in phis))

>        phis[event] = phi(tableFor(event, journal));

>    }

>  }

>  return phis;

>}

Используя >forEach мы делаем запись чуть короче и гораздо чище.

>function gatherCorrelations(journal) {

>  var phis = {};

>  journal.forEach(function(entry) {

>    entry.events.forEach(function(event) {

>      if (!(event in phis))

>        phis[event] = phi(tableFor(event, journal));

>    });

>  });

>  return phis;

>}

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

Функции, оперирующие другими функциями – либо принимая их в качестве аргументов, либо возвращая их, называются функциями высшего порядка. Если вы уже поняли, что функции – это всего лишь переменные, ничего особенного в существовании таких функций нет. Термин происходит из математики, где различия между функциями и другими значениями воспринимаются более строго.

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