Ova jezična značajka JavaScripta može vam pomoći da sredite svoj kod i dat će vam novo razumijevanje kako funkcije funkcioniraju.

Curried funkcije mogu pomoći da vaš JavaScript kôd bude čitljiviji i izražajniji. Tehnika curryinga idealna je kada želite rastaviti složenu logiku na manje, samostalne dijelove koda kojima se lakše upravlja.

Naučite sve o curried funkcijama u JavaScriptu, kako koristiti tehniku ​​currying funkcija za stvaranje djelomično primijenjene funkcije, kao i slučajeve korištenja iz stvarnog života za curried funkcije i djelomično primijenjene funkcije.

Što je currying?

Currying je dobio ime po matematičaru Haskellu B. Curry, a koncept proizlazi iz Lambda računa. Currying uzima funkciju koja prima više od jednog parametra i rastavlja je u niz unarnih (jednoparametarskih) funkcija. Drugim riječima, curried funkcija uzima samo jedan parametar odjednom.

Osnovni primjer curryinga

Ispod je primjer curried funkcije:

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

The izgraditi sendvič() funkcija vraća drugu funkciju — anonimnu funkciju koja prima sastojak2 argument. Zatim, ova anonimna funkcija vraća drugu anonimnu funkciju koja prima sastojak3. Konačno, ova zadnja funkcija vraća literal predloška, ​​način formatiranje nizova u JavaScriptu.

Ono što ste stvorili je ugniježđena funkcija gdje svaka funkcija poziva onu ispod sebe dok ne dođemo do kraja. Sad, kad nazoveš izgraditi sendvič() i proslijedite mu jedan parametar, vratit će dio funkcije čije argumente tek trebate dati:

console.log(buildSandwich("Bacon"))

Iz izlaza možete vidjeti da buildSandwich vraća funkciju:

Da biste dovršili poziv funkcije, trebate unijeti sva tri argumenta:

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

Ovaj kod prosljeđuje "Bacon" prvoj funkciji, "Lettuce" drugoj i "Tomato" zadnjoj funkciji. Drugim riječima, izgraditi sendvič() funkcija je zapravo podijeljena na tri funkcije, pri čemu svaka funkcija prima samo jedan parametar.

Iako je savršeno ispravno curry korištenjem tradicionalnih funkcija, svo gniježđenje može postati prilično ružno što dublje idete. Da biste to zaobišli, možete koristiti funkcije strelica i iskoristiti njihovu čistiju sintaksu:

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

Ova refaktorirana verzija je sažetija, što je prednost korištenja funkcije strelica u odnosu na regularne funkcije. Funkciju možete pozvati na isti način kao što ste učinili s prethodnom:

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

Djelomično primijenjene Curry funkcije

Djelomično primijenjene funkcije uobičajena su uporaba curryinga. Ova tehnika podrazumijeva dostavljanje samo potrebnih argumenata odjednom (umjesto dobavljanja svih argumenata). Kad god pozovete funkciju prosljeđivanjem svih potrebnih parametara, kažete da ste "primijenili" tu funkciju.

Pogledajmo primjer:

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

Ispod je kari verzija množenja:

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

The curriedMultiply() funkcija prima x argument za prvu funkciju i g za drugu funkciju, onda množi obje vrijednosti.

Za izradu prve djelomično primijenjene funkcije, pozovite curriedMultiple() s prvim parametrom i dodijelite vraćenu funkciju varijabli:

const timesTen = curriedMultiply(10)

U ovom trenutku kod je "djelomično primijenio". curriedMultiply() funkcija. Dakle, nazovite kad god želite putaDeset(), samo trebate proslijediti jedan broj i broj će se automatski pomnožiti s 10 (što je pohranjeno unutar primijenjene funkcije):

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

To vam omogućuje nadogradnju jedne složene funkcije stvaranjem više prilagođenih funkcija iz nje, svaka sa svojom zaključanom funkcijom.

Pogledajte primjer koji je bliži stvarnom slučaju korištenja za web razvoj. Ispod imate a updateElemText() funkcija koja uzima element iskaznica na prvom pozivu, sadržaj na drugom pozivu, a zatim ažurira element na temelju iskaznica i sadržaj koji ste dostavili:

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!")

Sastav funkcije s curried funkcijama

Druga uobičajena uporaba curryinga je funkcionalna kompozicija. To vam omogućuje pozivanje malih funkcija, određenim redoslijedom, i njihovo kombiniranje u jednu, složeniju funkciju.

Na primjer, na hipotetskoj web stranici e-trgovine, evo tri funkcije koje biste mogli pokrenuti jednu za drugom (točnim redoslijedom):

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.`);
}

Primijetite da ovaj kod koristi neka ključna riječ za definiranje dovršiNarudžba() funkcija. To vam omogućuje ponovno dodjeljivanje vrijednosti varijabli i dio je kako određivanje opsega funkcionira u JavaScriptu.

Zatim morate pozvati funkcije obrnutim redoslijedom (iznutra prema van) jer prvo želite dodati kupce:

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

To će vam dati sljedeći rezultat:

Ako biste gore navedene funkcije napisali na uobičajen način, kod bi izgledao otprilike ovako:

functionaddCustomer(...args) {
returnfunctionprocessOrder(...args) {
returnfunctioncompleteOrder(...args) {
// end
}
}
}

Kada nazovete addCustomer() funkciju i proslijedite argumente, počinjete iznutra i idete prema vrhu funkcije.

Pretvorite normalnu funkciju u curried funkciju pomoću Curry funkcije

Ako planirate puno koristiti curried funkcije, možete pojednostaviti proces s pomoćnom funkcijom.

Ova funkcija će pretvoriti bilo koju normalnu funkciju u curried funkciju. Koristi rekurziju za rukovanje bilo kojim brojem argumenata.

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

return fn(...args);
}
}

Ova funkcija će prihvatiti bilo koju standardnu ​​pisanu funkciju koja prima više od jednog parametra, vraćajući verziju te funkcije s karijem. Da biste ga vidjeli na djelu, upotrijebite ovaj primjer funkcije koja uzima tri parametra i dodaje ih zajedno:

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

Za konverziju ove funkcije, nazovite curry() funkcija i prolaz ukupno kao argument:

const curriedTotal = curry(total)

Da biste pozvali funkciju, trebate samo proslijediti sve argumente:

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

Više o funkcijama u JavaScriptu

Funkcije JavaScripta iznimno su fleksibilne, a currying funkcije samo su mali dio toga. Postoje mnoge druge vrste funkcija poput funkcija strelica, funkcija konstruktora i anonimnih funkcija. Upoznavanje s ovim funkcijama i njihovim komponentama ključno je za svladavanje JavaScripta.