Представляем вам перевод статьи Sukhjinder Arora, опубликованной на ресурсе Bits and Pieces. Узнайте под катом о функциях высшего порядка в JavaScript и о некоторых других функциях, встроенных в этот язык.

Фото NESA by Makers с сайта Unsplash
Обучаясь программированию на JavaScript, вы наверняка сталкивались с понятием функций высшего порядка. Хотя это понятие может показаться пугающим, на самом деле все не так сложно.
Именно благодаря способности работать с функциями высшего порядка, JavaScript подходит для функционального программирования.
Функции высшего порядка широко распространены в языке JavaScript. Если вы проработали с ним какое-то время, весьма вероятно, что вы использовали такие функции, даже не догадываясь об этом.
Чтобы получить полное представление о функциях высшего порядка, вам прежде всего нужно понять, что такое функциональное программирование и функции первого класса.
Совет: многократное применение функций JavaScript часто ведет к появлению дубликатов. Чтобы избежать этого, воспользуйтесь Bit (GitHub). Вы сможете с легкостью находить новые функции, делиться ими и применять их повторно с минимальными изменениями в управлении. Пробуйте, не стесняйтесь.
Если не вдаваться в подробности, функциональное программирование — это программирование, при котором одни функции передаются в качестве аргументов другим функциям и возвращают третьи функции в качестве значений. В функциональном программировании мы мыслим и оперируем функциями.
Функциональное программирование производится на таких языках, как JavaScript, Haskell, Clojure, Scala и Erlang.
Обучаясь работе с JavaScript, вы, скорее всего, слышали, что для него функции — это граждане первого класса. Дело в том, что в JavaScript, как и в любом другом языке функционального программирования, функции являются объектами.
Конкретно для JavaScript функции — это объекты особого рода (объекты
Чтобы показать, что функции в JavaScript являются объектами, мы можем проделать что-то вроде этого:
Примечание: хотя вышеописанное и прекрасно работает в JavaScript, злоупотреблять подобным не стоит. Нельзя присваивать случайные свойства функторам — лучше используйте обычные объекты.
В JavaScript все, что вы можете проделать с другими сущностями, такими как объект, строка (string) или число, применимо и к функциям. Их можно передавать, в том числе в качестве аргументов другим функциям (тогда они называются callback-функциями или функциями обратного вызова), присваивать их переменным и так далее. Вот почему функции JavaScript называются функциями первого класса.
JavaScript позволяет присваивать функции переменным. Например:
Также их можно передавать. Например:
Мы можем передавать функции в качестве аргументов другим функциям. Например:
Итак, теперь, зная, что такое функции первого класса, давайте обратимся к функциям высшего порядка в JavaScript.
Функции высшего порядка — это функции, которые работают с другими функциями, принимая функцию как аргумент или возвращая функцию как результат.
Примерами функций высшего порядка, которые уже встроены в язык, являются
Давайте рассмотрим несколько примеров встроенных функций высшего порядка и сравним их с решениями, при которых функции высшего порядка не используются.
Array.prototype.map
Метод
Callback-функция, передаваемая методу
Рассмотрим это на нескольких примерах.
Пример №1
Допустим, у нас есть массив чисел, и из него мы хотим создать новый массив, в котором каждое число из начального массива было бы удвоено. Как мы можем решить эту задачу при помощи функции высшего порядка и без нее?
Без функции высшего порядка:
При помощи функции высшего порядка
Код можно сделать еще короче при помощи стрелочной функции
Пример №2
Скажем, у нас есть массив, содержащий годы рождения нескольких людей, и из него мы хотим создать новый массив, в котором будут их возрасты.
Без функции высшего порядка:
При помощи функции высшего порядка
Array.prototype.filter
Метод
Рассмотрим это на нескольких примерах.
Пример №1
Представим, что у нас есть массив, содержащий объекты со свойствами «имя» и «возраст». Из него мы хотим создать новый массив, в котором будут указаны только совершеннолетние (от восемнадцати и старше).
Без функции высшего порядка:
При помощи функции высшего порядка
Array.prototype.reduce
Метод
Callback-функция принимает четыре аргумента:
Если параметр
Если параметр
Пример №1
Предположим, нам нужно найти сумму чисел массива.
При помощи функции высшего порядка
Каждый раз, когда callback-функция применяется к каждому значению из массива, аргумент
Кроме того, мы можем передать этой функции начальное значение:
Без функции высшего порядка:
Как видите, при помощи функции высшего порядка код можно сделать аккуратнее, короче и емче.
До этого момента мы рассматривали различные функции высшего порядка, встроенные в язык. Пора создать собственную функцию высшего порядка.
Представим, что в JavaScript не было бы собственного метода
Скажем, у нас есть массив строк, и из него мы хотим создать массив интегралов, в котором каждый элемент будет представлять длину строки из начального массива.
В приведенном примере мы создали функцию высшего порядка
Callback-функция
М�� узнали, что такое функции высшего порядка, и рассмотрели некоторые встроенные в язык функции. Также мы узнали, как создавать собственные функции высшего порядка.
Если вкратце, функции высшего порядка работают как обычные функции, но обладают дополнительной способностью получать другие функции как аргумент и возвращать их как результат.
Вот, собственно, и все. Если данная статья показалась вам полезной, вы можете также подписаться на меня на Medium и в Twitter. Не стесняйтесь — комментируйте, если у вас есть вопросы! Я буду рад помочь. :)

Фото NESA by Makers с сайта Unsplash
Обучаясь программированию на JavaScript, вы наверняка сталкивались с понятием функций высшего порядка. Хотя это понятие может показаться пугающим, на самом деле все не так сложно.
Именно благодаря способности работать с функциями высшего порядка, JavaScript подходит для функционального программирования.
Функции высшего порядка широко распространены в языке JavaScript. Если вы проработали с ним какое-то время, весьма вероятно, что вы использовали такие функции, даже не догадываясь об этом.
Чтобы получить полное представление о функциях высшего порядка, вам прежде всего нужно понять, что такое функциональное программирование и функции первого класса.
Совет: многократное применение функций JavaScript часто ведет к появлению дубликатов. Чтобы избежать этого, воспользуйтесь Bit (GitHub). Вы сможете с легкостью находить новые функции, делиться ими и применять их повторно с минимальными изменениями в управлении. Пробуйте, не стесняйтесь.
Что такое функциональное программирование
Если не вдаваться в подробности, функциональное программирование — это программирование, при котором одни функции передаются в качестве аргументов другим функциям и возвращают третьи функции в качестве значений. В функциональном программировании мы мыслим и оперируем функциями.
Функциональное программирование производится на таких языках, как JavaScript, Haskell, Clojure, Scala и Erlang.
Что такое функции первого класса
Обучаясь работе с JavaScript, вы, скорее всего, слышали, что для него функции — это граждане первого класса. Дело в том, что в JavaScript, как и в любом другом языке функционального программирования, функции являются объектами.
Конкретно для JavaScript функции — это объекты особого рода (объекты
Function, или функторы). Например:function greeting() {
console.log('Hello World');
}
// Invoking the function
greeting(); // prints 'Hello World'Чтобы показать, что функции в JavaScript являются объектами, мы можем проделать что-то вроде этого:
// We can add properties to functions like we do with objects
greeting.lang = 'English';
// Prints 'English'
console.log(greeting.lang);Примечание: хотя вышеописанное и прекрасно работает в JavaScript, злоупотреблять подобным не стоит. Нельзя присваивать случайные свойства функторам — лучше используйте обычные объекты.
В JavaScript все, что вы можете проделать с другими сущностями, такими как объект, строка (string) или число, применимо и к функциям. Их можно передавать, в том числе в качестве аргументов другим функциям (тогда они называются callback-функциями или функциями обратного вызова), присваивать их переменным и так далее. Вот почему функции JavaScript называются функциями первого класса.
Присваивание функций переменным
JavaScript позволяет присваивать функции переменным. Например:
const square = function(x) {
return x * x;
}
// prints 25
square(5);Также их можно передавать. Например:
const foo = square;
// prints 36
foo(6);
Передача функций в качестве аргументов
Мы можем передавать функции в качестве аргументов другим функциям. Например:
function formalGreeting() {
console.log("How are you?");
}
function casualGreeting() {
console.log("What's up?");
}
function greet(type, greetFormal, greetCasual) {
if(type === 'formal') {
greetFormal();
} else if(type === 'casual') {
greetCasual();
}
}
// prints 'What's up?'
greet('casual', formalGreeting, casualGreeting);Итак, теперь, зная, что такое функции первого класса, давайте обратимся к функциям высшего порядка в JavaScript.
Функции высшего порядка
Функции высшего порядка — это функции, которые работают с другими функциями, принимая функцию как аргумент или возвращая функцию как результат.
Примерами функций высшего порядка, которые уже встроены в язык, являются
Array.prototype.map, Array.prototype.filter и Array.prototype.reduce.Функции высшего порядка в действии
Давайте рассмотрим несколько примеров встроенных функций высшего порядка и сравним их с решениями, при которых функции высшего порядка не используются.
Array.prototype.map
Метод
map() создает новый массив с результатом вызова передаваемой функции для каждого элемента начального массива. Метод map() берет каждое значение callback-функции и создает новый мас��ив, используя эти значения.Callback-функция, передаваемая методу
map(), принимает три аргумента: element, index и array.Рассмотрим это на нескольких примерах.
Пример №1
Допустим, у нас есть массив чисел, и из него мы хотим создать новый массив, в котором каждое число из начального массива было бы удвоено. Как мы можем решить эту задачу при помощи функции высшего порядка и без нее?
Без функции высшего порядка:
const arr1 = [1, 2, 3];
const arr2 = [];
for(let i = 0; i < arr1.length; i++) {
arr2.push(arr1[i] * 2);
}
// prints [ 2, 4, 6 ]
console.log(arr2);При помощи функции высшего порядка
map:const arr1 = [1, 2, 3];
const arr2 = arr1.map(function(item) {
return item * 2;
});
console.log(arr2);Код можно сделать еще короче при помощи стрелочной функции
const arr1 = [1, 2, 3];
const arr2 = arr1.map(item => item * 2);
console.log(arr2);Пример №2
Скажем, у нас есть массив, содержащий годы рождения нескольких людей, и из него мы хотим создать новый массив, в котором будут их возрасты.
Без функции высшего порядка:
const birthYear = [1975, 1997, 2002, 1995, 1985];
const ages = [];
for(let i = 0; i < birthYear.length; i++) {
let age = 2018 - birthYear[i];
ages.push(age);
}
// prints [ 43, 21, 16, 23, 33 ]
console.log(ages);При помощи функции высшего порядка
map:const birthYear = [1975, 1997, 2002, 1995, 1985];
const ages = birthYear.map(year => 2018 - year);
// prints [ 43, 21, 16, 23, 33 ]
console.log(ages);Array.prototype.filter
Метод
filter() создает новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции. Callback-функция, передаваемая методу filter(), принимает три аргумента: element, index и array.Рассмотрим это на нескольких примерах.
Пример №1
Представим, что у нас есть массив, содержащий объекты со свойствами «имя» и «возраст». Из него мы хотим создать новый массив, в котором будут указаны только совершеннолетние (от восемнадцати и старше).
Без функции высшего порядка:
const persons = [
{ name: 'Peter', age: 16 },
{ name: 'Mark', age: 18 },
{ name: 'John', age: 27 },
{ name: 'Jane', age: 14 },
{ name: 'Tony', age: 24},
];
const fullAge = [];
for(let i = 0; i < persons.length; i++) {
if(persons[i].age >= 18) {
fullAge.push(persons[i]);
}
}
console.log(fullAge);При помощи функции высшего порядка
filter:const persons = [
{ name: 'Peter', age: 16 },
{ name: 'Mark', age: 18 },
{ name: 'John', age: 27 },
{ name: 'Jane', age: 14 },
{ name: 'Tony', age: 24},
];
const fullAge = persons.filter(person => person.age >= 18);
console.log(fullAge);Array.prototype.reduce
Метод
reduce применяет функцию к каждому значению массива, сводя его к одному значению. Метод reduce принимает два аргумента: - callback-функцию, которую требуется обработать;
- необязательный параметр
initialValue(первый аргумент при первом вызове функции).
Callback-функция принимает четыре аргумента:
accumulator, currentValue, currentIndex, sourceArray.Если параметр
initialValue был передан, аргумент accumulator будет равен аргументу initialValue, а аргумент currentValue — первому элементу массива. Если параметр
initialValue передан не был, аргумент accumulator будет равен первому элементу массива, а в качестве аргумента currentValue будет взят второй элемент массива.Пример №1
Предположим, нам нужно найти сумму чисел массива.
При помощи функции высшего порядка
reduce:const arr = [5, 7, 1, 8, 4];
const sum = arr.reduce(function(accumulator, currentValue) {
return accumulator + currentValue;
});
// prints 25
console.log(sum);Каждый раз, когда callback-функция применяется к каждому значению из массива, аргумент
accumulator сохраняет результат предыдущего действия, возвращенный функцией, а currentValue принимает следующее значение массива. По завершении работы результат сохраняется в переменной sum.Кроме того, мы можем передать этой функции начальное значение:
const arr = [5, 7, 1, 8, 4];
const sum = arr.reduce(function(accumulator, currentValue) {
return accumulator + currentValue;
}, 10);
// prints 35
console.log(sum);Без функции высшего порядка:
const arr = [5, 7, 1, 8, 4];
let sum = 0;
for(let i = 0; i < arr.length; i++) {
sum = sum + arr[i];
}
// prints 25
console.log(sum);Как видите, при помощи функции высшего порядка код можно сделать аккуратнее, короче и емче.
Создание собственной функции высшего порядка
До этого момента мы рассматривали различные функции высшего порядка, встроенные в язык. Пора создать собственную функцию высшего порядка.
Представим, что в JavaScript не было бы собственного метода
map. Мы могли бы построить его самостоятельно, тем самым создав собственную функцию высшего порядка.Скажем, у нас есть массив строк, и из него мы хотим создать массив интегралов, в котором каждый элемент будет представлять длину строки из начального массива.
const strArray = ['JavaScript', 'Python', 'PHP', 'Java', 'C'];
function mapForEach(arr, fn) {
const newArray = [];
for(let i = 0; i < arr.length; i++) {
newArray.push(
fn(arr[i])
);
}
return newArray;
}
const lenArray = mapForEach(strArray, function(item) {
return item.length;
});
// prints [ 10, 6, 3, 4, 1 ]
console.log(lenArray);В приведенном примере мы создали функцию высшего порядка
mapForEach, которая принимает в качестве аргументов массив и callback-функцию fn. Эта функция циклично применяется к каждому элементу массива и вызывает callback-функцию fn в рамках вызова функции newArray.push в каждой итерации.Callback-функция
fn принимает текущий элемент начального массива и возвращает значение длины этого элемента, которое сохраняется внутри нового массива newArray. После завершения итерации массив newArray возвращается в качестве результата и назначается массивом lenArray.Заключение
М�� узнали, что такое функции высшего порядка, и рассмотрели некоторые встроенные в язык функции. Также мы узнали, как создавать собственные функции высшего порядка.
Если вкратце, функции высшего порядка работают как обычные функции, но обладают дополнительной способностью получать другие функции как аргумент и возвращать их как результат.
Вот, собственно, и все. Если данная статья показалась вам полезной, вы можете также подписаться на меня на Medium и в Twitter. Не стесняйтесь — комментируйте, если у вас есть вопросы! Я буду рад помочь. :)
