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

Во-первых, давайте выясним, что такое функции высшего порядка. Функции высшего порядка (HOF) — это функции, которые работают с другими функциями, либо принимая их в качестве аргументов, либо возвращая их. Операции здесь относятся либо к возврату функции в качестве результата, либо к принятию одной или нескольких функций в качестве аргументов. Не обязательно выполнять обе задачи. Функция считается функцией высшего порядка, если она выполняет одно или другое действие.

Вопрос, который следует задать себе: «Как это возможно? Почему функция может принимать другую функцию в качестве аргумента или возвращать функцию? Как функция может принимать другую функцию в качестве аргумента или возвращать функцию?» Знание этих ответов действительно поможет вам понять, как HOFработаютпод капотом. Помните свои типы данных? Тот, который вы выучили, когда проходили свой первый курс Javascript? Вам сказали, что javascript имеет два типа типов данных:

  1. Примитивные типы данных
  2. Непримитивные типы данных.

Простыми словами, примитивные типы данных — это типы данных, которые не являются объектами и включают в себя Strings, Numbers, Boolean, Symbols, Bigint, Null и Undefined. К непримитивным типам данных относятся массивы, объекты и функции. Теперь это может немного сбить с толку, потому что типом объекта является Object. Я пытаюсь обратить ваше внимание на этот факт, потому что он очень важен. Объекты основаны на ключах, используют методы и принимают свойства. Вам было бы интересно узнать, что массив – это объект, который работает немного иначе, чем объекты, потому что они основаны на индексах и используют итераторы другого типа, а также по другим причинам. (узнайте больше о массивах, и вы будете поражены). Вам также было бы интересно узнать, что функции тоже являются объектами. В некотором смысле они представляют собой продвинутый тип объектов. Точно так же, как в шахматах, где ферзь имеет те же силы, что и ладья, слон и пешка, функции имеют все свойства функций и встроенных в них объектов. (Я много играю в шахматы, и это лучший способ объяснить функции, чтобы вы поняли эти концепции). Функции JavaScript — это объекты «первоклассного». Поэтому:

  • У них есть встроенные свойства и методы, такие как свойство name и метод .toString().
  • К ним можно добавлять свойства и методы.
  • Их можно передавать в качестве аргументов и возвращать из других функций.
  • Их можно присваивать переменным, элементам массива и другим объектам.
//Assign a function to a variable originalFunc
const originalFunc = (num) => { return num + 2 };
//Re-assign the function to a new variable newFunc
const newFunc = originalFunc;
//Access the function's name property
newFunc.name; //'originalFunc'
//Return the function's body as a string
newFunc.toString(); //'(num) => { return num + 2 }'
//Add our own isMathFunction property to the function
newFunc.isMathFunction = true;
//Pass the function as an argument
const functionNameLength = (func) => { return func.name.length };
functionNameLength(originalFunc); //12
//Return the function
const returnFunc = () => { return newFunc };
returnFunc(); //[Function: originalFunc]

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

Функция обратного вызова

Функция обратного вызова — это функция, передаваемая в другую функцию в качестве аргумента, которая затем вызывается внутри внешней функции для завершения какой-либо подпрограммы или действия. Это означает, что функция обратного вызова является типом HOF.

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

Метод .reduce()

Метод .reduce() перебирает массив и возвращает одно значение.

const arrayOfNumbers = [11, 12, 13, 14];
const sum = arrayOfNumbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
});
console.log(sum); // 50

В приведенном выше примере кода метод .reduce() суммирует все элементы массива. Он принимает функцию обратного вызова с двумя параметрами (accumulator, currentValue) в качестве аргументов. На каждой итерации accumulator — это значение, возвращаемое последней итерацией, а currentValue — это текущий элемент. При желании можно передать второй аргумент, который действует как начальное значение аккумулятора.

Метод .map()

Метод .map() выполняет функцию обратного вызова для каждого элемента массива. Он возвращает новый массив, состоящий из значений, возвращаемых функцией обратного вызова.

Исходный массив не изменяется, а возвращенный массив может содержать элементы, отличные от исходного массива.

const siblings = ['Paul', 'Francis', 'Faith', 'Purity'];
// add string after each sibling
const announcements = siblings.map(sibling => {
return sibling + ' is my sibling.';
})
console.log(announcements);

В приведенном выше примере кода метод .map() используется для добавления строки ' is my sibling.' в конец каждого элемента в массиве siblings.

Метод .filter()

Метод .filter() выполняет функцию обратного вызова для каждого элемента массива. Функция обратного вызова для каждого из элементов должна возвращать либо true, либо false. Возвращаемый массив — это новый массив с любыми элементами, для которых функция обратного вызова возвращает true.

const randomNumbers = [14, 21, 52, 24, 49];
const filteredArray = randomNumbers.filter(n => {
return n > 15;
});

В приведенном выше примере кода массив filteredArray будет содержать все элементы randomNumbers, кроме 14.

Понимание этих концепций поможет вам понять, как работают замыкания. О закрытии напишу позже.

Спасибо за прочтение.