Tato funkce jazyka JavaScript vám může pomoci uklidit váš kód a poskytne vám nové ocenění toho, jak funkce fungují.
Curried funkce mohou pomoci učinit váš kód JavaScript čitelnějším a výraznějším. Technika kari je ideální, když chcete složitou logiku rozdělit na menší, samostatné a lépe ovladatelné části kódu.
Zjistěte vše o funkcích curry v JavaScriptu, jak používat techniku currying k vytvoření částečně aplikované funkce, stejně jako případy skutečného použití jak pro curried funkce, tak pro částečně aplikované funkcí.
Co je kari?
Currying je pojmenován po matematikovi Haskellovi B. Curry a koncept pochází z lambda kalkulu. Currying bere funkci, která přijímá více než jeden parametr, a rozděluje ji na řadu unárních (jednoparametrových) funkcí. Jinými slovy, funkce curried zabírá vždy pouze jeden parametr.
Základní příklad kari
Níže je uveden příklad funkce curried:
functionbuildSandwich(ingredient1) {
return(ingredient2) => {
return(ingredient3) => {
return`${ingredient1},${ingredient2},${ingredient3}`
}
}
}
The buildSandwich() funkce vrací jinou funkci — anonymní funkci, která přijímá přísada2 argument. Potom tato anonymní funkce vrátí jinou anonymní funkci, která obdrží přísada 3. Nakonec tato poslední funkce vrátí šablonový literál, způsob formátování řetězců v JavaScriptu.
To, co jste vytvořili, je vnořená funkce, kde každá funkce volá tu pod ní, dokud nedosáhneme konce. Teď, když zavoláš buildSandwich() a předáte mu jeden parametr, vrátí část funkce, jejíž argumenty ještě musíte poskytnout:
console.log(buildSandwich("Bacon"))
Z výstupu můžete vidět, že buildSandwich vrací funkci:
Chcete-li dokončit volání funkce, budete muset zadat všechny tři argumenty:
buildSandwich("Bacon")("Lettuce")("Tomato")
Tento kód předá první funkci „Bacon“, druhé funkci „Salát“ a poslední funkci „Tomato“. Jinými slovy, buildSandwich() funkce je skutečně rozdělena do tří funkcí, přičemž každá funkce přijímá pouze jeden parametr.
I když je naprosto platné používat kari pomocí tradičních funkcí, veškeré vnořování může být tím hlouběji, čím hlouběji, pěkně ošklivé. Chcete-li to obejít, můžete použít funkce šipek a využít jejich čistší syntaxi:
const buildMeal = ingred1 =>ingred2 =>ingred3 =>
`${ingred1}, ${ingred2}. ${ingred3}`;
Tato refaktorovaná verze je stručnější, výhoda použití funkce šipky vs běžné funkce. Funkci můžete volat stejným způsobem jako u předchozí:
buildMeal("Bacon")("Lettuce")("Tomato")
Částečně aplikované funkce kari
Částečně aplikované funkce jsou běžné použití kari. Tato technika znamená dodání pouze potřebných argumentů najednou (spíše než dodání všech argumentů). Kdykoli vyvoláte funkci předáním všech požadovaných parametrů, říkáte, že jste tuto funkci „aplikovali“.
Podívejme se na příklad:
const multiply = (x, y) => x * y;
Níže je kari verze multiply:
const curriedMultiply = x =>y => x * y;
The curriedMultiply() funkce přijímá X argument pro první funkci a y pro druhou funkci pak obě hodnoty vynásobí.
Chcete-li vytvořit první částečně použitou funkci, zavolejte curriedMultiple() s prvním parametrem a přiřaďte vrácenou funkci proměnné:
const timesTen = curriedMultiply(10)
V tomto okamžiku kód „částečně použil“. curriedMultiply() funkce. Takže kdykoli budete chtít zavolat timesTen(), stačí předat jedno číslo a číslo se automaticky vynásobí 10 (které je uloženo uvnitř použité funkce):
console.log(timesTen(8)) // 80
To vám umožní stavět na jediné komplexní funkci tím, že z ní vytvoříte několik vlastních funkcí, z nichž každá má svou vlastní funkci.
Podívejte se na příklad, který se blíží skutečnému případu použití při vývoji webu. Níže máte a updateElemText() funkce, která přebírá prvek id při prvním volání obsah při druhém volání a poté aktualizuje prvek na základě id a obsah, který jste 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!")
Funkce Složení S Curried Funkce
Dalším běžným použitím kari je kompozice funkcí. To vám umožní volat malé funkce v určitém pořadí a kombinovat je do jediné, složitější funkce.
Například na hypotetickém webu elektronického obchodu jsou zde tři funkce, které byste mohli chtít spouštět jednu po druhé (v přesném pořadí):
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šimněte si, že tento kód používá nechat klíčové slovo pro definování dokončit objednávku() funkce. To vám umožní znovu přiřadit hodnotu proměnné a je součástí jak funguje rozsah v JavaScriptu.
Dále musíte volat funkce v opačném pořadí (zevnitř ven), protože nejprve chcete přidat zákazníky:
completeOrder = (processOrder(completeOrder));
completeOrder = (addCustomer(completeOrder));
completeOrder("1000")
Tím získáte následující výstup:
Pokud byste výše uvedené funkce napsali běžným způsobem, kód bude vypadat asi takto:
functionaddCustomer(...args) {
returnfunctionprocessOrder(...args) {
returnfunctioncompleteOrder(...args) {
// end
}
}
}
Když zavoláte na addCustomer() funkce a předáte argumenty, začínáte zevnitř a propracováváte se až k vrcholu funkce.
Převeďte normální funkci na funkci Curried pomocí funkce Curry
Pokud plánujete hodně využívat curried funkce, můžete proces zefektivnit pomocí pomocné funkce.
Tato funkce převede jakoukoli normální funkci na funkci curried. Ke zpracování libovolného počtu argumentů používá rekurzi.
const curry = (fn) => {
return curried = (...args) => {
if (fn.length !== args.length) {
return curried.bind(null, ...args)
}
return fn(...args);
}
}
Tato funkce přijme jakoukoli standardní napsanou funkci, která přijímá více než jeden parametr a vrací curried verzi této funkce. Chcete-li to vidět v akci, použijte tuto ukázkovou funkci, která vezme tři parametry a přidá je dohromady:
const total = (x, y, z) => x + y + z
Chcete-li tuto funkci převést, zavolejte kari() fungovat a projít celkový jako argument:
const curriedTotal = curry(total)
Nyní k volání funkce stačí předat všechny argumenty:
console.log(curriedTotal(10)(20)(30)) // 60
Více o funkcích v JavaScriptu
Funkce JavaScriptu jsou extrémně flexibilní a funkce currying jsou jen malou částí toho. Existuje mnoho dalších typů funkcí, jako jsou funkce šipek, funkce konstruktoru a anonymní funkce. Seznámení s těmito funkcemi a jejich součástmi je klíčové pro zvládnutí JavaScriptu.