Тази функция на езика на JavaScript може да ви помогне да подредите кода си и ще ви даде нова представа за това как работят функциите.

Curried функциите могат да ви помогнат да направите вашия JavaScript код по-четлив и изразителен. Техниката на къри е идеална, когато искате да разбиете сложната логика на по-малки, самостоятелни, по-управляеми части от код.

Научете всичко за карираните функции в JavaScript, как да използвате техниката за кариране на функции за създаване частично приложени функции, както и случаи на употреба в реалния живот както за кари функции, така и за частично приложени функции.

Какво е къри?

Кърирането е кръстено на математика Хаскел Б. Къри, а концепцията произлиза от ламбда смятането. Currying взема функция, която получава повече от един параметър и я разделя на поредица от унарни (еднопараметърни) функции. С други думи, къри функция приема само един параметър наведнъж.

Основен пример за къри

По-долу е даден пример за къри функция:

functionbuildSandwich(ingredient1) 
instagram viewer
{
return(ingredient2) => {
return(ingredient3) => {
return`${ingredient1},${ingredient2},${ingredient3}`
}
}
}

The buildSandwich() функция връща друга функция — анонимна функция, която получава съставка2 аргумент. След това тази анонимна функция връща друга анонимна функция, която получава съставка3. И накрая, тази последна функция връща литерала на шаблона, начин на форматиране на низове в 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;

По-долу е версията с къри на multiply:

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

The curriedMultiply() функцията получава х аргумент за първата функция и г за втората функция, тогава тя умножава и двете стойности.

За да създадете първата частично приложена функция, извикайте curriedMultiple() с първия параметър и присвоете върнатата функция на променлива:

const timesTen = curriedMultiply(10)

На този етап кодът е „приложил частично“ curriedMultiply() функция. Така че винаги, когато искате, звънете пъти Десет(), просто трябва да му предадете едно число и числото автоматично ще бъде умножено по 10 (което се съхранява в приложената функция):

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

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

Разгледайте пример, който е по-близо до реален случай на използване на уеб разработка. По-долу имате a updateElemText() функция, която приема елемент документ за самоличност при първото извикване, съдържанието при второто извикване и след това актуализира елемента въз основа на документ за самоличност и съдържанието, което сте предоставили:

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
}
}
}

Когато се обадите на 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

За да конвертирате тази функция, извикайте къри() функция и пас обща сума като аргумент:

const curriedTotal = curry(total)

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

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

Повече за функциите в JavaScript

Функциите на JavaScript са изключително гъвкави и къри функциите са само малка част от това. Има много други типове функции като функции със стрелки, конструкторски функции и анонимни функции. Запознаването с тези функции и техните компоненти е от ключово значение за овладяването на JavaScript.