В этой статье я хочу кратко объяснить, что такое функции высшего порядка (сокр. ФВП) и как их использовать. Если вы не знакомы с ФВП, тогда вы будете удивлены, ведь работаете с ними постоянно что на JavaScript, что на TypeScript.
Что такое функции высшего порядка?
Функция высшего порядка - это функция, которая либо принимает другую функцию в качестве аргумента, либо возвращает функцию. Проще говоря, можно сказать, что функция высшего порядка - это обертка для другой функции.
Вы можете спросить: Зачем функции принимать другую функцию в качестве аргумента?
Самый простой способ объяснить этот функционал в JavaScript экосистеме - это колбэки.
Колбэки повсюду, так что функции высшего порядка встречаются сплошь и рядом.
Функции высшего порядка, которые вы могли знать
Давайте посмотрим на самые популярные функции высшего порядка, с которыми вы точно сталкивались при разработке на JavaScript или TypeScript.
setTimeout()
Да, setTimeout
- это функция высшего порядка. Она принимает другую функцию в качестве аргумента и вызывает ее по прошествии определенного количества времени. В данном примере, по прошествии примерно 100 миллисекунд.
setTimeout(() => {
console.log('Hello');
}, 100);
Array.find()
Array.find()
также очень популярная функция высшего порядка, которая появляется в большинстве проектов по несколько раз. Но вообще-то она чуть более сложная. Потому что наша функция внутри find()
просто возвращает булево значение, но сама Array.find()
возвращает либо undefined, либо искомый элемент.
const arr: Record<string, number>[] = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
const res: Record<string, number> = arr.find((item: Record<string, number>) => {
return item.id === 3;
});
// res = { id: 3 }
Array.filter()
Еще одна функция класса Array используется для фильтрации массивов. Эта функция также принимает другую функцию как аргумент и возвращает новый отфильтрованный массив.
const arr: string[] = ['Anna', 'Emily', 'John', 'Kevin', 'Michelle', 'Ryan', 'Yvonne'];
const res: string[] = arr.filter((name: string) => {
return name.includes('i');
});
// res = ['Emily', 'Kevin', 'Michelle']
Создание своей функции высшего порядка
Вышеприведенные примеры показывают, как ФВП принимают другие функции в качестве аргумента, поэтому я хочу показать второй вариант использования функций высшего порядка, когда они возвращают функцию.
Для начала мы создадим новую функцию и назовем ее requiredAge
, она будет принимать число как аргумент. Это число - это минимальный требуемый возраст. А возвращать она будет другую функцию, которая в свою очередь будет возвращать булево значение.
Затем мы вызовем эту функцию дважды на 7 и 8 строчках, где мы установим минимальный возраст.
В конце мы вызовем внутреннюю функцию requiredAge
4 раза, проверяя, подходит ли наш возраст.
function requiredAge(minimum: number): Function {
return (age: number): boolean => {
return age >= minimum;
};
}
const canDrinkBeer: Function = requiredAge(16);
const canDriveCar: Function = requiredAge(18);
console.log(canDrinkBeer(10)); // -> вернет false
console.log(canDrinkBeer(20)); // -> вернет true
console.log(canDriveCar(17)); // -> вернет false
console.log(canDriveCar(25)); // -> вернет true
Что ж, этот концепт звучит довольно сложно, но на самом деле это не так, и мы постоянно имеем дело с функциями высшего порядка.
Спасибо за прочтение. Надеюсь, я смог освежить ваши знания, а, возможно, вы узнали для себя что-то новое, что еще лучше.
Surof1n
Друзья, пожалуйста, подумайте прежде чем использовать реализации из этой статьи, на ревью вам не скажут спасибо.
Если вам действительно требуется что-то подобное, то оставьте ваши типы в покое и не пишите явные аннотации типов в этих примерах:
Я бы хотел разобрать данный пример дважды
Если вам действительно потребуется фильтрация массива в котором находятся данные литералы, то взгляните на данную реализацию:
muturgan
Я предпочитаю везде явно задавать возвращаемые типы.
Просто для функции requireAge в качестве возвращаемого типа следует указать не Function а более отражающее суть (age: number) => boolean