Tämä JavaScript-kielen ominaisuus voi auttaa siivoamaan koodisi ja antaa sinulle uuden käsityksen toimintojen toiminnasta.

Curried-funktiot voivat auttaa tekemään JavaScript-koodistasi luettavamman ja ilmeisemmän. Currying-tekniikka on ihanteellinen, kun haluat hajottaa monimutkaisen logiikan pienemmiksi, itsenäisiksi, paremmin hallittavissa oleviksi koodin osiksi.

Opi kaikki curry-funktioista JavaScriptissä, kuinka voit käyttää funktion curry-tekniikkaa luomiseen osittain sovelletut funktiot sekä tosielämän käyttötapaukset sekä curry-funktioille että osittain sovelletuille funktioille toimintoja.

Mitä Currying on?

Currying on nimetty matemaatikko Haskell B: n mukaan. Curry, ja käsite on peräisin lambda-laskennasta. Currying ottaa funktion, joka vastaanottaa useamman kuin yhden parametrin, ja jakaa sen joukoksi unaarisia (yhden parametrin) funktioita. Toisin sanoen curry-funktio ottaa vain yhden parametrin kerrallaan.

Perusesimerkki currysta

Alla on esimerkki curry-funktiosta:

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

The buildSandwich() funktio palauttaa toisen funktion — anonyymin funktion, joka vastaanottaa ainesosa 2 Perustelu. Sitten tämä anonyymi funktio palauttaa toisen anonyymin funktion, joka vastaanottaa ainesosa 3. Lopuksi tämä viimeinen funktio palauttaa mallin literaalin, tapana muotoile merkkijonoja JavaScriptissä.

Luomasi on sisäkkäinen funktio, jossa jokainen funktio kutsuu sen alla olevaa funktiota, kunnes saavutamme sen. Nyt kun soitat buildSandwich() ja välität sille yhden parametrin, se palauttaa funktion osan, jonka argumentteja et vielä anna:

console.log(buildSandwich("Bacon"))

Voit nähdä lähdöstä, että buildSandwich palauttaa funktion:

Suorittaaksesi funktiokutsun, sinun on annettava kaikki kolme argumenttia:

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

Tämä koodi välittää "pekonin" ensimmäiseen funktioon, "salaatti" toiseen ja "tomaatti" viimeiseen toimintoon. Toisin sanoen, buildSandwich() funktio on todella jaettu kolmeen funktioon, joista jokainen saa vain yhden parametrin.

Vaikka curryn käyttäminen perinteisillä toiminnoilla on täysin pätevää, kaikki pesimäkohdat voivat muuttua melko rumaksi, mitä syvemmälle pääset. Voit kiertää tämän käyttämällä nuolifunktioita ja hyödyntää niiden puhtaampaa syntaksia:

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

Tämä uudelleen muotoiltu versio on ytimekkäämpi, käytön etu nuolifunktiot vs. tavalliset funktiot. Voit kutsua funktiota samalla tavalla kuin edellisessä:

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

Osittain sovelletut curryfunktiot

Osittain sovelletut toiminnot ovat yleinen curryn käyttö. Tämä tekniikka edellyttää vain tarvittavien argumenttien toimittamista kerrallaan (eikä kaikkien argumenttien toimittamista). Aina kun kutsut funktion ohittamalla kaikki vaaditut parametrit, sanot, että olet "käyttänyt" kyseistä funktiota.

Katsotaanpa esimerkkiä:

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

Alla on multiplyn curry-versio:

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

The curriedMultiply() toiminto vastaanottaa x argumentti ensimmäiselle funktiolle ja y toiselle funktiolle, se kertoo molemmat arvot.

Luo ensimmäinen osittain käytetty funktio soittamalla curriedMultiple() ensimmäisellä parametrilla ja määritä palautettu funktio muuttujalle:

const timesTen = curriedMultiply(10)

Tässä vaiheessa koodia on "osittain sovellettu". curriedMultiply() toiminto. Joten milloin haluat soittaa timesTen(), sinun tarvitsee vain antaa sille yksi numero ja numero kerrotaan automaattisesti 10:llä (joka on tallennettu käytetyn funktion sisään):

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

Tämän avulla voit rakentaa yhden monimutkaisen toiminnon päälle luomalla siitä useita mukautettuja toimintoja, joista jokaisessa on omat toiminnallisuutensa lukittuina.

Katso esimerkkiä, joka on lähempänä todellista verkkokehityksen käyttötapausta. Alla on a päivitäElemText() funktio, joka ottaa elementin id ensimmäisessä puhelussa toisen puhelun sisällön ja päivittää sitten elementin id ja sille toimittamasi sisältö:

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

Toimintojen kokoonpano Curried-funktioilla

Toinen yleinen curryn käyttötapa on funktiokoostumus. Näin voit kutsua pieniä toimintoja tietyssä järjestyksessä ja yhdistää ne yhdeksi, monimutkaisemmiksi funktioksi.

Esimerkiksi hypoteettisella verkkokauppasivustolla on kolme toimintoa, jotka saatat haluta suorittaa peräkkäin (tarkassa järjestyksessä):

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

Huomaa, että tämä koodi käyttää antaa avainsana määrittääksesi Tee tilaus() toiminto. Tämän avulla voit määrittää arvon uudelleen muuttujalle ja se on osa muuttujaa miten laajuus toimii JavaScriptissä.

Seuraavaksi sinun on kutsuttava funktiot käänteisessä järjestyksessä (sisältä ulos), koska haluat lisätä asiakkaat ensin:

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

Tämä antaa sinulle seuraavan tulosteen:

Jos kirjoitat yllä olevat funktiot tavallisella tavalla, koodi näyttää suunnilleen tältä:

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

Kun soitat addCustomer() funktio ja välität argumentit, aloitat sisältä ja etenet funktion huipulle.

Muunna normaali funktio Curry-funktioksi Curry-funktiolla

Jos aiot käyttää curry-funktioita paljon, voit virtaviivaistaa prosessia aputoiminnolla.

Tämä toiminto muuntaa minkä tahansa normaalin funktion curry-funktioksi. Se käyttää rekursiota käsittelemään minkä tahansa määrän argumentteja.

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

return fn(...args);
}
}

Tämä funktio hyväksyy kaikki tavalliset kirjoitetut funktiot, jotka vastaanottavat useamman kuin yhden parametrin, ja palauttaa funktion curry-version. Näet sen toiminnassa käyttämällä tätä esimerkkifunktiota, joka ottaa kolme parametria ja lisää ne yhteen:

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

Muuntaaksesi tämän funktion, soita curry() toimi ja pass kaikki yhteensä argumenttina:

const curriedTotal = curry(total)

Nyt funktion kutsumiseksi sinun on vain välitettävä kaikki argumentit:

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

Lisätietoja JavaScriptin funktioista

JavaScriptin toiminnot ovat erittäin joustavia ja curry-funktiot ovat vain pieni osa sitä. On olemassa monia muita funktioita, kuten nuolifunktiot, konstruktorifunktiot ja anonyymit funktiot. Näihin toimintoihin ja niiden osiin tutustuminen on avain JavaScriptin hallitsemiseen.