В этой статье мы должны отдать дань уважения функциям высшего порядка и компонентам высшего порядка.

Все мы знаем, что когда я говорю высшее, приближается что-то королевское. Это только я?

Будьте готовы, они не похожи на обычные функции. Это функции ВЫСШЕГО ПОРЯДКА.

Вы говорите, что делает их такими особенными? Что ж, они не принимают строки или массивы, как обычные функции. LAME, это слабый соус. Функции высшего порядка принимают ФУНКЦИИ в качестве входных данных.

Мой Бог. Ты вообще можешь это сделать? В JavaScript да, вы можете делать что угодно, лол.

Функции в сценариях JavaScripts похожи на объекты, они называются гражданами первого класса. Опять больше королевской семьи. Вы думали, эта статья была для крестьян?

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

Итак, теперь, когда мы знаем, что у нас есть возможность передавать функции нашим функциям. Что это на самом деле означает? Что мы делаем с этой функцией?

И разве это не похоже на обратный звонок? Когда мы передаем функцию другой функции для последующего запуска, она называется функцией обратного вызова. Таким образом, она вызывается функцией более высокого порядка.

Итак ... из этого я понимаю, что:

function higherOrderFunction(callback) {
}

Вот пример, который вы, вероятно, довольно часто видели в своем коде:

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

Таким образом, map () является функцией высшего порядка. А наша анонимная функция - это обратный вызов.

let array = [1, 2, 3, 4];
let doubles = array.map(function(n){
    return n * 2
}) 
console.log (doubles); // [ 2, 4, 6, 8 ]

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

Напоминаем, как работает map ():

  • Карта выполняет итерацию по всем элементам в массиве и применяет логику
  • Возвращает новый массив

Итак, давайте добавим новую карту к прототипу массива. Таким образом, мы можем использовать его во всех будущих массивах.

Это просто, просто выполните Array.prototype. ‹Имя вашей функции›. Не знали, что можно вот так модифицировать JavaScript? Так что круто.

logic is the callback function we pass to the higher order function
Array.prototype.newMapFunction = function ( logic ) {
  // create new array
  let array = []
  // loop through all elements 
  for (let i = 0; i < this.length; i++) {
    // Call the logic function which can be anything on all items
    // Push the result in our new array
     array.push (logic (this[i])); 
  }
  // return new array
  return array; 
}

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

Давайте посмотрим, как использовать нашу карту.

Предположим, мы написали программу, которая принимает названия городов. Итак, наши данные были городами, хранящимися в массиве. Мы хотим, чтобы некоторые функции обновляли отображение этих городов по-разному.

Мы могли бы сделать что-то вроде:

function covertToAbbreviations (cities) {
//  for loop
//  apply logic for abbreviations
// return new cities array
}
function createGreetingFromCity (cities) {
//  for loop
//  apply logic for greeting
// return new cities array
}

Но нам нужно будет повторить этот цикл и другую подобную логику несколько раз. Кажется, это не лучший способ делать что-то. Неа.

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

Итак, начнем с наших данных:

let array = [‘toronto’,’ottawa’,’montreal’,’vancouver’];

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

function covertToAbbreviations (string) {
  return string.substr(0,3);
}
function createGreetingFromCity (string) {
  return `Welcome to ${string.toUpperCase()}`;
}

Мы передаем наши маленькие функции в качестве логического параметра нашей функции карты высшего порядка, и она будет применять ее к каждому элементу. Хорошо, давай попробуем!

let shortHandCities = array.newMapFunction(covertToAbbreviations);
let greetingCities = array.newMapFunction(createGreetingFromCity);
console.log (shortHandCities);
Output: [ 'tor', 'ott', 'mon', 'van' ]
console.log (greetingCities);
Output:
[ 'Welcome to TORONTO',
'Welcome to OTTAWA',
'Welcome to MONTREAL',
'Welcome to VANCOUVER' ]

ВАУ! Прохладный.

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

Я обещал также поговорить о компонентах более высокого порядка, так что, как и функции, которые принимают функции в качестве аргумента, они являются компонентами, которые принимают компоненты в качестве аргументов!

Компоненты более высокого порядка принимают компонент в качестве аргумента и возвращают новый компонент.

Случаи применения:

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

Компонент более высокого порядка преобразует компонент в другой компонент. Обратите внимание, что HOC не изменяет входной компонент. Скорее HOC составляет исходный компонент, оборачивая его в компонент-контейнер.

В React, допустим, у нас есть много компонентов, которым нужно добавить функцию поиска, поэтому мы делаем следующее

  • обернутый компонент может быть любым компонентом в вашем коде
  • к нему добавляется дополнительная логика поиска, которая возвращается в render ()
const withSearch = WrappedComponent => {   
  class WithSearch extends React.Component {     
    // additional search functionality
    render() {       
       return (
        <>           
          <input onChange={this.handleSearch} 
                 value={searchTerm}
                 type="text" 
                 placeholder="Search"           
           />           
          <WrappedComponent data={filteredProducts} />        
        </>
      );  
    }
 }   
 return WithSearch
}

И использовать это:

const SearchHOC = withSearch(MyComponent);

Надеюсь, вам понравилась эта статья!