Эта функция языка JavaScript поможет привести в порядок ваш код и даст вам новое представление о том, как работают функции.
Каррированные функции могут помочь сделать ваш код JavaScript более читабельным и выразительным. Техника каррирования идеальна, когда вы хотите разбить сложную логику на более мелкие, автономные и более управляемые фрагменты кода.
Узнайте все о каррированных функциях в JavaScript, как использовать технику каррирования функций для создания частично прикладные функции, а также реальные варианты использования как каррированных, так и частично прикладных функций. функции.
Что такое каррирование?
Карринг назван в честь математика Хаскелла Б. Карри, и эта концепция происходит от лямбда-исчисления. Каррирование берет функцию, которая получает более одного параметра, и разбивает ее на ряд унарных функций (с одним параметром). Другими словами, каррированная функция принимает только один параметр за раз.
Базовый пример каррирования
Ниже приведен пример каррированной функции:
functionbuildSandwich(ingredient1) {
return(ingredient2) => {
return(ingredient3) => {
return`${ingredient1},${ingredient2},${ingredient3}`
}
}
}
построитьСэндвич() функция возвращает другую функцию — анонимную функцию, которая получает ингредиент2 аргумент. Затем эта анонимная функция возвращает другую анонимную функцию, которая получает ингредиент3. Наконец, последняя функция возвращает литерал шаблона, способ форматирование строк в JavaScript.
То, что вы создали, — это вложенная функция, в которой каждая функция вызывает ту, которая находится под ней, пока мы не дойдем до конца. Теперь, когда вы позвоните построитьСэндвич() и передать ему один параметр, он вернет часть функции, аргументы которой вам еще предстоит предоставить:
console.log(buildSandwich("Bacon"))
Из вывода видно, что buildSandwich возвращает функцию:
Чтобы завершить вызов функции, вам необходимо предоставить все три аргумента:
buildSandwich("Bacon")("Lettuce")("Tomato")
Этот код передает «Бекон» в первую функцию, «Салат» во вторую и «Помидор» в последнюю функцию. Другими словами, построитьСэндвич() Функция фактически разбита на три функции, каждая из которых получает только один параметр.
Хотя каррирование с использованием традиционных функций вполне допустимо, чем глубже вы погружаетесь, тем вложенность может стать довольно уродливой. Чтобы обойти это, вы можете использовать стрелочные функции и воспользоваться их более чистым синтаксисом:
const buildMeal = ingred1 =>ingred2 =>ingred3 =>
`${ingred1}, ${ingred2}. ${ingred3}`;
Эта реорганизованная версия более лаконична, что является преимуществом использования стрелочные функции против обычных функций. Вы можете вызвать функцию так же, как и предыдущую:
buildMeal("Bacon")("Lettuce")("Tomato")
Частично применяемые функции карри
Частично применяемые функции — это обычное использование каррирования. Этот метод предполагает предоставление только необходимых аргументов за раз (а не предоставление всех аргументов). Всякий раз, когда вы вызываете функцию, передавая все необходимые параметры, вы говорите, что «применили» эту функцию.
Давайте посмотрим на пример:
const multiply = (x, y) => x * y;
Ниже приведена каррированная версия умножения:
const curriedMultiply = x =>y => x * y;
карридMultiply() функция получает Икс аргумент для первой функции и й для второй функции она умножает оба значения.
Чтобы создать первую частично примененную функцию, вызовите карриедМножественный() с первым параметром и присвойте возвращаемую функцию переменной:
const timesTen = curriedMultiply(10)
На этом этапе код «частично применил» карридMultiply() функция. Поэтому в любое время, когда вы захотите позвонить разДесять(), вам просто нужно передать ему одно число, и оно будет автоматически умножено на 10 (которое хранится внутри прикладной функции):
console.log(timesTen(8)) // 80
Это позволяет вам использовать одну сложную функцию, создавая из нее несколько пользовательских функций, каждая из которых имеет свою собственную функциональность.
Взгляните на пример, который ближе к реальному варианту использования веб-разработки. Ниже у вас есть обновитьЭлемтекст() функция, которая принимает элемент идентификатор при первом вызове, содержимое при втором вызове, а затем обновляет элемент на основе идентификатор и содержание, которое вы ему предоставили:
const updateElemText = id = content
=> document.querySelector(`#${id}`).textContent = content// Lock the element's id into the function:
const updateHeaderText = updateElemText('header')
// Update the header text
updateHeaderText("Hello World!")
Композиция функций с каррированными функциями
Другое распространенное применение каррирования — композиция функций. Это позволяет вызывать небольшие функции в определенном порядке и объединять их в одну, более сложную функцию.
Например, на гипотетическом веб-сайте электронной коммерции есть три функции, которые вы можете запускать одну за другой (в точном порядке):
const addCustomer = fn =>(...args) => {
console.log("Saving customer info")
return fn(...args)
}const processOrder = fn =>(...args) => {
console.log(`processing order #${args[0]}`)
return fn(...args);
}
let completeOrder = (...args) => {
console.log(`Order #${[...args].toString()} completed.`);
}
Обратите внимание, что этот код использует позволять ключевое слово для определения полныйОрдер() функция. Это позволяет вам переназначить значение переменной и является частью как область видимости работает в JavaScript.
Далее вам нужно вызвать функции в обратном порядке (изнутри наружу), поскольку сначала вы хотите добавить клиентов:
completeOrder = (processOrder(completeOrder));
completeOrder = (addCustomer(completeOrder));
completeOrder("1000")
Это даст вам следующий результат:
Если бы вы написали вышеуказанные функции обычным способом, код выглядел бы примерно так:
functionaddCustomer(...args) {
returnfunctionprocessOrder(...args) {
returnfunctioncompleteOrder(...args) {
// end
}
}
}
Когда вы звоните в добавитьКлиент() функцию и передать аргументы, вы начинаете изнутри и продвигаетесь к вершине функции.
Преобразование обычной функции в каррированную функцию с помощью функции карри
Если вы планируете часто использовать каррированные функции, вы можете упростить процесс с помощью вспомогательной функции.
Эта функция преобразует любую обычную функцию в каррированную функцию. Он использует рекурсию для обработки любого количества аргументов.
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
Чтобы преобразовать эту функцию, вызовите карри() функционировать и проходить общий в качестве аргумента:
const curriedTotal = curry(total)
Теперь, чтобы вызвать функцию, вам просто нужно передать все аргументы:
console.log(curriedTotal(10)(20)(30)) // 60
Подробнее о функциях в JavaScript
Функции JavaScript чрезвычайно гибки, и функции каррирования — лишь малая часть этого. Существует множество других типов функций, таких как стрелочные функции, функции-конструкторы и анонимные функции. Знакомство с этими функциями и их компонентами является ключом к освоению JavaScript.