Как каррировать функции в JavaScript

Категория: веб разработка

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

Узнайте все о каррированных функциях в JavaScript, как использовать технику каррирования для создания частично примененных функций, а также о реальных случаях использования как каррированных функций, так и частично примененных функций.

Что такое Каррирование? Каррирование получило свое имя в честь математика Хаскела Б. Карри, и концепция происходит из лямбда-исчисления. Каррирование превращает функцию, принимающую более одного параметра, в серию унарных (однопараметровых) функций. Другими словами, каррированная функция принимает только один параметр за раз.

Простой Пример Каррирования Вот пример каррированной функции:

function buildSandwich(ingredient1) {
return (ingredient2) => {
return (ingredient3) => {
return `${ingredient1}, ${ingredient2}, ${ingredient3}`;
};
};
}

Функция buildSandwich() возвращает другую функцию - анонимную функцию, которая принимает аргумент ingredient2. Затем эта анонимная функция возвращает еще одну анонимную функцию, принимающую ingredient3. Наконец, эта последняя функция возвращает шаблонный литерал, способ форматирования строк в JavaScript.

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

console.log(buildSandwich("Bacon"));

Из вывода видно, что buildSandwich возвращает функцию:

Чтобы завершить вызов функции, вам нужно предоставить все три аргумента:

buildSandwich("Bacon")("Lettuce")("Tomato");

Этот код передает "Bacon" первой функции, "Lettuce" второй и "Tomato" последней функции. Другими словами, функция buildSandwich() разделена на три функции, каждая из которых принимает только один параметр.

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

const buildMeal = ingred1 => ingred2 => ingred3 =>
`${ingred1}, ${ingred2}, ${ingred3}`;

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

buildMeal("Bacon")("Lettuce")("Tomato");

Частично Примененные Каррированные Функции Частично примененные функции - это распространенное использование каррирования. Эта техника заключается в предоставлении только нужных аргументов по мере необходимости (вместо предоставления всех аргументов). Когда вы вызываете функцию, передавая все необходимые параметры, вы говорите, что вы "применили" эту функцию.

Давайте рассмотрим пример:

const multiply = (x, y) => x * y;

Вот каррированная версия умножения:

const curriedMultiply = x => y => x * y;

Функция curriedMultiply() принимает аргумент x для первой функции и y для второй функции, затем умножает оба значения.

Чтобы создать первую частично примененную функцию, вызовите curriedMultiply() с первым параметром и присвойте возвращенную функцию переменной:

const timesTen = curriedMultiply(10);

На этом этапе код "частично применил" функцию curriedMultiply(). Так что каждый раз, когда вы хотите вызвать timesTen(), вам нужно просто передать ей одно число, и число автоматически умножится на 10 (которое хранится внутри примененной функции):

console.log(timesTen(8)); // 80

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

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

const updateElemText = (id, content) =>
document.querySelector(`#${id}`).textContent = content;
// Зафиксируйте идентификатор элемента в функции:
const updateHeaderText = updateElemText('header');

// Обновите текст заголовка
updateHeaderText("Hello World!");

Композиция Функций с Каррированными Функциями Еще одним распространенным использованием каррирования является композиция функций. Это позволяет вам вызывать небольшие функции в определенном порядке и объединять их в одну более сложную функцию.

Например, в гипотетическом интернет-магазине у вас есть три функции, которые вы хотели бы выполнить одну за другой (в точном порядке):

const addCustomer = fn => (...args) => {
console.log("Сохранение информации о клиенте");
return fn(...args);
};
const processOrder = fn => (...args) => {
console.log(`Обработка заказа №${args[0]}`);
return fn(...args);
};

let completeOrder = (...args) => {
console.log(`Заказ №${[...args].toString()} выполнен.`);
};

Обратите внимание, что в этом коде используется ключевое слово let для определения функции completeOrder(). Это позволяет вам присвоить значение переменной и является частью того, как работает область видимости в JavaScript.

Затем вам нужно вызвать функции в обратном порядке (изнутри наружу), потому что вы хотите сначала добавить клиентов:

completeOrder = processOrder(completeOrder);
completeOrder = addCustomer(completeOrder);
completeOrder("1000");

Это даст вам следующий вывод:

Если бы вы написали вышеуказанные функции обычным способом, код выглядел бы примерно так:

function addCustomer(...args) {
return function processOrder(...args) {
return function completeOrder(...args) {
// конец
};
};
}

Когда вы вызываете функцию addCustomer() и передаете аргументы, вы начинаете с внутренней функции и двигаетесь от нее к верхушке функции.

Преобразование Обычной Функции в Каррированную Функцию с Помощью Функции Каррирования Если вы планируете часто использовать каррированные функции, вы можете упростить процесс с помощью вспомогательной функции.

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

const curry = (fn) => {
return curried = (...args) => {
if (fn.length !== args.length) {
return curried.bind(null, ...args);
}
return fn(...args);
};
};

Эта функция примет любую стандартную функцию, принимающую более одного параметра, и вернет каррированную версию этой функции. Чтобы увидеть ее в действии, используйте этот пример функции, которая принимает три параметра и складывает их:

const total = (x, y, z) => x + y + z;

Чтобы преобразовать эту функцию, вызовите функцию curry() и передайте total в качестве аргумента:

const curriedTotal = curry(total);

Теперь, чтобы вызвать функцию, вам просто нужно передать все аргументы:

console.log(curriedTotal(10)(20)(30)); // 60

Больше о Функциях в JavaScript Функции в JavaScript чрезвычайно гибки и каррирование функций - это всего лишь малая часть этого. Существует много других типов функций, таких как стрелочные функции, конструкторы функций и анонимные функции. Знакомство с этими функциями и их компонентами ключево для освоения JavaScript.





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

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *



Карта сайта
Copyright © 2023