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

React

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

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

С функциями в JavaScript вы можете:

  • Хранить их в качестве переменных.
  • Использовать их в массивах.
  • Назначать их в качестве свойств объекта (методов).
  • Передавать их в качестве аргументов.
  • Возвращать их из других функций.

Как и любой другой фрагмент данных. Вот самое главное, что вам нужно понять.

Функции работают с данными

Строки — это данные

sayHi = (name) => `Hi, ${name}!`;
result = sayHi('User');

console.log(result); // 'Hi, User!'

Числа — это данные

double = (x) => x * 2;
result = double(4);

console.log(result); // 8

Булевой тип данных — это данные

getClearance = (allowed) => allowed ?
  'Access granted' :
  'Access denied';

result1 = getClearance(true);
result2 = getClearance(false);

console.log(result1); // 'Access granted'
console.log(result2); // 'Access denied'

Объекты — это данные

getFirstName = (obj) => obj.firstName;
result = getFirstName({
  firstName: 'Yazeed'
});

console.log(result); // 'Yazeed'

Массивы — это данные

len = (array) => array.length;
result = len([1, 2, 3]);

console.log(result); // 3

Эти 5 типов данных являются объектами первого класса в любом из распространенных языков программирования.

Что делает их “первоклассными”? Вы можете передавать их, хранить их в переменных и массивах, использовать их в качестве исходных данных для вычислений. Вы можете использовать их, как и любой другой фрагмент данных.

Функции тоже могут быть данными

Функции в качестве аргументов

isEven = (num) => num % 2 === 0;
result = [1, 2, 3, 4].filter(isEven);

console.log(result); // [2, 4]

Видите как filter использует isEven, чтобы решить, какие числа оставить? Функция isEven была аргументом другой функции.

Функция isEven вызывается функцией filter для каждого числа и использует возвращаемое значение true или false, чтобы определить, следует оставить число или выбросить.

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

add = (x) => (y) => x + y;

add запрашивает два аргумента, но по отдельности. Эта функция, запрашивающая только x, которая возвращает функцию, запрашивающую только y.

Опять же, это возможно только потому, что JavaScript позволяет функциям быть возвращаемым значением — таким же, как строки, числа, булевые значения и т.д.

Если захотите, вы по-прежнему сможете немедленно предоставить x и y двойным вызовом функции.

result = add(10)(20);
console.log(result); // 30

Или же x сейчас, а y позже.

add10 = add(10);
result = add10(20);
console.log(result); // 30

Давайте вернемся к последнему примеру. add10 — это результат вызова функции add с одним аргументом. Попробуйте залогировать (logging) это в консоли.

add10 — это функция, которая берет y и возвращает x + y. После того, как вы предоставите y, она поспешит вычислить и вернуть ваш конечный результат.

Возможность повторного использования

Вероятно, самое большое преимущество функций высшего порядка — это возможность повторного использования. Без этих функций, методы массивов JavaScript — map, filter, и reduce не существовали бы!

Ниже представлен список пользователей. Мы собираемся сделать кое-какие вычисления с этой информацией.

users = [{
  name: 'Yazeed',
  age: 25
}, {
  name: 'Sam',
  age: 30
}, {
  name: 'Bill',
  age: 20
}];

Map

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

getName = (user) => user.name;
usernames = [];

for (let i = 0; i < users.length; i++) {
  const name = getName(users[i]);

  usernames.push(name);
}

console.log(usernames);
// ["Yazeed", "Sam", "Bill"]

Но мы может сделать так:

usernames = users.map(getName);

console.log(usernames);
// ["Yazeed", "Sam", "Bill"]

Filter

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

startsWithB = (string) => string
  .toLowerCase()
  .startsWith('b');

namesStartingWithB = [];

for (let i = 0; i < users.length; i++) {
  if (startsWithB(users[i].name)) {
    namesStartingWithB.push(users[i]);
  }
}

console.log(namesStartingWithB);
// [{ "name": "Bill", "age": 20 }]

Но мы может сделать так:

namesStartingWithB = users
  .filter((user) => startsWithB(user.name));

console.log(namesStartingWithB);
// [{ "name": "Bill", "age": 20 }]

Reduce

Да, это касается и метода reduce…Нельзя сделать столько крутых вещей без функций высшего порядка! 😁

total = 0;

for (let i = 0; i < users.length; i++) {
  total += users[i].age;
}

console.log(total);
// 75

Но как насчет этого?

totalAge = users
  .reduce((total, user) => user.age + total, 0);

console.log(totalAge);
// 75

Заключение

  • Строки, числа, булевые значения, массивы и объекты могут храниться в качестве переменных, массивов, аргументов или методов.
  • JavaScript обрабатывает все функции одинаково.
  • Map, filter и reduce значительно упрощают преобразование, поиск и суммирование списков.

Специально для сайта ITWORLD.UZ. Новость взята с сайта NOP::Nuances of programming