Táto funkcia jazyka JavaScript vám môže pomôcť upratať váš kód a poskytne vám nové pochopenie toho, ako funkcie fungujú.
Curried funkcie môžu pomôcť urobiť váš kód JavaScript čitateľnejším a výraznejším. Technika kari je ideálna, keď chcete rozdeliť zložitú logiku na menšie, samostatné a lepšie spravovateľné časti kódu.
Dozviete sa všetko o funkciách curried v JavaScripte, o tom, ako používať techniku currying na vytváranie čiastočne aplikované funkcie, ako aj prípady skutočného použitia pre obe funkcie, ako aj čiastočne aplikované funkcie.
Čo je kari?
Currying je pomenovaný po matematikovi Haskellovi B. Curry a koncept pochádza z lambda kalkulu. Currying berie funkciu, ktorá prijíma viac ako jeden parameter, a rozdeľuje ju do série unárnych (jednoparametrových) funkcií. Inými slovami, funkcia curried berie naraz iba jeden parameter.
Základný príklad kari
Nižšie je uvedený príklad funkcie curried:
functionbuildSandwich(ingredient1) {
return(ingredient2) => {
return(ingredient3) => {
return`${ingredient1},${ingredient2},${ingredient3}`
}
}
}
The buildSandwich() funkcia vracia inú funkciu — anonymnú funkciu, ktorá prijíma prísada2 argument. Potom táto anonymná funkcia vráti inú anonymnú funkciu, ktorá dostane prísada 3. Nakoniec táto posledná funkcia vráti doslovný vzor šablóny, spôsob formátovanie reťazcov v JavaScripte.
To, čo ste vytvorili, je vnorená funkcia, kde každá funkcia volá tú pod ňou, kým sa nedostaneme na koniec. Teraz, keď zavoláš buildSandwich() a odošlete mu jeden parameter, vráti časť funkcie, ktorej argumenty ešte musíte poskytnúť:
console.log(buildSandwich("Bacon"))
Z výstupu môžete vidieť, že buildSandwich vracia funkciu:
Na dokončenie volania funkcie by ste museli zadať všetky tri argumenty:
buildSandwich("Bacon")("Lettuce")("Tomato")
Tento kód odovzdá prvej funkcii „Slanina“, druhej funkcii „Hlávkový šalát“ a poslednej funkcii „paradajka“. Inými slovami, buildSandwich() funkcia je skutočne rozdelená do troch funkcií, pričom každá funkcia dostáva iba jeden parameter.
Aj keď je úplne platné, že karí pomocou tradičných funkcií, všetky vnorenia môžu byť dosť škaredé, čím hlbšie sa dostanete. Aby ste to obišli, môžete použiť funkcie šípok a využiť ich čistejšiu syntax:
const buildMeal = ingred1 =>ingred2 =>ingred3 =>
`${ingred1}, ${ingred2}. ${ingred3}`;
Táto refaktorovaná verzia je stručnejšia, výhoda použitia funkcie šípok verzus bežné funkcie. Funkciu môžete zavolať rovnakým spôsobom ako v predchádzajúcej:
buildMeal("Bacon")("Lettuce")("Tomato")
Čiastočne aplikované funkcie kari
Čiastočne aplikované funkcie sú bežným používaním kari. Táto technika znamená dodanie iba potrebných argumentov naraz (namiesto dodania všetkých argumentov). Kedykoľvek vyvoláte funkciu odovzdaním všetkých požadovaných parametrov, hovoríte, že ste túto funkciu „aplikovali“.
Pozrime sa na príklad:
const multiply = (x, y) => x * y;
Nižšie je kariova verzia multiply:
const curriedMultiply = x =>y => x * y;
The curriedMultiply() funkcia prijíma X argument pre prvú funkciu a r pre druhú funkciu, potom obe hodnoty vynásobí.
Ak chcete vytvoriť prvú čiastočne aplikovanú funkciu, zavolajte curriedMultiple() s prvým parametrom a priraďte vrátenú funkciu premennej:
const timesTen = curriedMultiply(10)
V tomto bode kód „čiastočne aplikoval“. curriedMultiply() funkciu. Takže kedykoľvek budete chcieť zavolať timesTen(), stačí zadať jedno číslo a číslo sa automaticky vynásobí 10 (ktoré je uložené vo vnútri použitej funkcie):
console.log(timesTen(8)) // 80
To vám umožní stavať na jedinej komplexnej funkcii vytvorením viacerých vlastných funkcií, z ktorých každá má svoju vlastnú funkciu.
Pozrite si príklad, ktorý je bližšie k skutočnému prípadu použitia pri vývoji webu. Nižšie máte a updateElemText() funkcia, ktorá preberá prvok id pri prvom hovore obsah pri druhom hovore a potom aktualizuje prvok na základe id a obsah, ktorý ste dodali:
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!")
Zloženie funkcií s Curried funkciami
Ďalším bežným použitím kari je funkčná kompozícia. To vám umožňuje volať malé funkcie v určitom poradí a skombinovať ich do jednej, zložitejšej funkcie.
Napríklad na hypotetickej webovej stránke elektronického obchodu sú tri funkcie, ktoré možno budete chcieť spustiť jednu po druhej (v presnom poradí):
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.`);
}
Všimnite si, že tento kód používa nech kľúčové slovo na definovanie kompletná objednávka() funkciu. To vám umožňuje priradiť hodnotu premennej a je súčasťou ako funguje rozsah v JavaScripte.
Ďalej musíte volať funkcie v opačnom poradí (zvnútra von), pretože najprv chcete pridať zákazníkov:
completeOrder = (processOrder(completeOrder));
completeOrder = (addCustomer(completeOrder));
completeOrder("1000")
To vám poskytne nasledujúci výstup:
Ak by ste vyššie uvedené funkcie napísali bežným spôsobom, kód bude vyzerať asi takto:
functionaddCustomer(...args) {
returnfunctionprocessOrder(...args) {
returnfunctioncompleteOrder(...args) {
// end
}
}
}
Keď zavoláte na addCustomer() funkciu a odovzdať argumenty, začínate zvnútra a postupujete až na vrchol funkcie.
Preveďte normálnu funkciu na funkciu Curried pomocou funkcie Curry
Ak plánujete veľa využívať funkcie curried, môžete proces zefektívniť pomocou pomocnej funkcie.
Táto funkcia prevedie akúkoľvek normálnu funkciu na funkciu curried. Používa rekurziu na spracovanie ľubovoľného počtu argumentov.
const curry = (fn) => {
return curried = (...args) => {
if (fn.length !== args.length) {
return curried.bind(null, ...args)
}
return fn(...args);
}
}
Táto funkcia bude akceptovať akúkoľvek štandardnú napísanú funkciu, ktorá prijíma viac ako jeden parameter a vracia curried verziu tejto funkcie. Ak ju chcete vidieť v akcii, použite túto vzorovú funkciu, ktorá berie tri parametre a pridáva ich dohromady:
const total = (x, y, z) => x + y + z
Ak chcete previesť túto funkciu, zavolajte kari() fungovať a prejsť Celkom ako argument:
const curriedTotal = curry(total)
Teraz na zavolanie funkcie stačí zadať všetky argumenty:
console.log(curriedTotal(10)(20)(30)) // 60
Viac o funkciách v JavaScripte
Funkcie JavaScriptu sú mimoriadne flexibilné a funkcie currying sú len malou časťou toho. Existuje mnoho ďalších typov funkcií, ako sú funkcie šípok, funkcie konštruktora a anonymné funkcie. Oboznámenie sa s týmito funkciami a ich komponentmi je kľúčom k zvládnutiu JavaScriptu.