Ta funkcja języka JavaScript może pomóc w uporządkowaniu kodu i pozwoli na nowe zrozumienie działania funkcji.
Funkcje Curry mogą pomóc uczynić kod JavaScript bardziej czytelnym i wyrazistym. Technika curry jest idealna, gdy chcesz rozbić złożoną logikę na mniejsze, samodzielne i łatwiejsze do zarządzania fragmenty kodu.
Dowiedz się wszystkiego o funkcjach curry w JavaScript, jak używać techniki curryingu do tworzenia częściowo zastosowane funkcje, a także rzeczywiste przypadki użycia zarówno funkcji curry, jak i częściowo zastosowanych Funkcje.
Co to jest curry?
Nazwa curry pochodzi od nazwiska matematyka Haskella B. Curry, a koncepcja wywodzi się z rachunku Lambda. Curry przyjmuje funkcję, która otrzymuje więcej niż jeden parametr, i dzieli ją na serię funkcji jednoargumentowych (jednoparametrowych). Innymi słowy, funkcja curry pobiera tylko jeden parametr na raz.
Podstawowy przykład curry
Poniżej znajduje się przykład funkcji curry:
functionbuildSandwich(ingredient1) {
return(ingredient2) => {
return(ingredient3) => {
return`${ingredient1},${ingredient2},${ingredient3}`
}
}
}
The zbuduj kanapkę() funkcja zwraca inną funkcję — funkcję anonimową, która otrzymuje składnik2 argument. Następnie ta funkcja anonimowa zwraca inną funkcję anonimową, która otrzymuje składnik 3. Na koniec ta ostatnia funkcja zwraca literał szablonu, w pewnym sensie formatowanie ciągów znaków w JavaScript.
Utworzyłeś funkcję zagnieżdżoną, w której każda funkcja wywołuje funkcję znajdującą się pod nią, aż dotrzemy do końca. Teraz, kiedy zadzwonisz zbuduj kanapkę() i przekażesz mu pojedynczy parametr, zwróci część funkcji, której argumentów jeszcze nie podałeś:
console.log(buildSandwich("Bacon"))
Z wyników widać, że buildSandwich zwraca funkcję:
Aby zakończyć wywołanie funkcji, musisz podać wszystkie trzy argumenty:
buildSandwich("Bacon")("Lettuce")("Tomato")
Ten kod przekazuje „Bakon” do pierwszej funkcji, „Sałata” do drugiej, a „Pomidor” do ostatniej funkcji. Inaczej mówiąc, zbuduj kanapkę() funkcja jest tak naprawdę podzielona na trzy funkcje, przy czym każda funkcja otrzymuje tylko jeden parametr.
Chociaż curry przy użyciu tradycyjnych funkcji jest całkowicie poprawne, całe zagnieżdżanie może stać się dość brzydkie, im głębiej sięgniesz. Aby obejść ten problem, możesz użyć funkcji strzałkowych i skorzystać z ich czystszej składni:
const buildMeal = ingred1 =>ingred2 =>ingred3 =>
`${ingred1}, ${ingred2}. ${ingred3}`;
Ta refaktoryzowana wersja jest bardziej zwięzła, co jest zaletą użycia funkcje strzałkowe a funkcje zwykłe. Możesz wywołać tę funkcję w taki sam sposób, jak w przypadku poprzedniej:
buildMeal("Bacon")("Lettuce")("Tomato")
Częściowo zastosowane funkcje curry
Częściowo zastosowane funkcje są powszechnym zastosowaniem curry. Technika ta polega na dostarczaniu tylko potrzebnych argumentów na raz (zamiast podawania wszystkich argumentów). Za każdym razem, gdy wywołujesz funkcję, przekazując wszystkie wymagane parametry, mówisz, że „zastosowałeś” tę funkcję.
Spójrzmy na przykład:
const multiply = (x, y) => x * y;
Poniżej znajduje się curry wersja multiply:
const curriedMultiply = x =>y => x * y;
The curryPomnóż() funkcja otrzymuje X argument pierwszej funkcji i y dla drugiej funkcji, to mnoży obie wartości.
Aby utworzyć pierwszą częściowo zastosowaną funkcję, wywołaj curryMultiple() z pierwszym parametrem i przypisz zwróconą funkcję do zmiennej:
const timesTen = curriedMultiply(10)
W tym momencie kod „częściowo zastosował” curryPomnóż() funkcjonować. Więc kiedy tylko chcesz, zadzwoń razy Dziesięć(), wystarczy przekazać mu jedną liczbę, a liczba zostanie automatycznie pomnożona przez 10 (która jest przechowywana wewnątrz zastosowanej funkcji):
console.log(timesTen(8)) // 80
Dzięki temu możesz budować na jednej złożonej funkcji, tworząc z niej wiele funkcji niestandardowych, z których każda ma własną, zablokowaną funkcjonalność.
Przyjrzyj się przykładowi, który jest bliższy rzeczywistemu przypadkowi użycia podczas tworzenia stron internetowych. Poniżej masz aktualizacjaElemText() funkcja, która pobiera element ID przy pierwszym wywołaniu treść drugiego wywołania, a następnie aktualizuje element w oparciu o ID i treści, które mu dostarczyłeś:
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!")
Kompozycja funkcyjna z funkcjami curry
Innym powszechnym zastosowaniem curry jest kompozycja funkcyjna. Umożliwia to wywoływanie małych funkcji w określonej kolejności i łączenie ich w jedną, bardziej złożoną funkcję.
Na przykład w hipotetycznej witrynie handlu elektronicznego znajdują się trzy funkcje, które możesz chcieć uruchomić jedna po drugiej (w dokładnej kolejności):
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.`);
}
Zauważ, że ten kod używa pozwalać słowo kluczowe określające ukończ zamówienie() funkcjonować. Pozwala to na ponowne przypisanie wartości do zmiennej i jest jej częścią jak działa zakres w JavaScript.
Następnie musisz wywołać funkcje w odwrotnej kolejności (od środka do zewnątrz), ponieważ chcesz najpierw dodać klientów:
completeOrder = (processOrder(completeOrder));
completeOrder = (addCustomer(completeOrder));
completeOrder("1000")
To da ci następujące dane wyjściowe:
Jeśli napiszesz powyższe funkcje w zwykły sposób, kod będzie wyglądał mniej więcej tak:
functionaddCustomer(...args) {
returnfunctionprocessOrder(...args) {
returnfunctioncompleteOrder(...args) {
// end
}
}
}
Kiedy zadzwonisz do dodaj klienta() funkcję i przekazujesz argumenty, zaczynasz od środka i kierujesz się ku górze funkcji.
Konwertuj funkcję normalną na funkcję Curry za pomocą funkcji Curry
Jeśli planujesz często korzystać z funkcji curry, możesz usprawnić proces za pomocą funkcji pomocniczej.
Ta funkcja przekonwertuje dowolną normalną funkcję na funkcję curry. Używa rekurencji do obsługi dowolnej liczby argumentów.
const curry = (fn) => {
return curried = (...args) => {
if (fn.length !== args.length) {
return curried.bind(null, ...args)
}
return fn(...args);
}
}
Ta funkcja akceptuje dowolną standardową funkcję zapisaną, która otrzymuje więcej niż jeden parametr, zwracając uproszczoną wersję tej funkcji. Aby zobaczyć to w akcji, użyj tej przykładowej funkcji, która pobiera trzy parametry i dodaje je do siebie:
const total = (x, y, z) => x + y + z
Aby przekonwertować tę funkcję, wywołaj metodę curry() funkcjonować i przejść całkowity jako argument:
const curriedTotal = curry(total)
Teraz, aby wywołać funkcję, wystarczy przekazać wszystkie argumenty:
console.log(curriedTotal(10)(20)(30)) // 60
Więcej o funkcjach w JavaScript
Funkcje JavaScriptu są niezwykle elastyczne, a funkcje curry to tylko niewielka część tego. Istnieje wiele innych typów funkcji, takich jak funkcje strzałkowe, funkcje konstruktora i funkcje anonimowe. Zapoznanie się z tymi funkcjami i ich komponentami jest kluczem do opanowania JavaScript.