chevron-left chevron-right

Piotr Nalepa Frontend, architektura i AI

Function currying – o co tu chodzi i jak tego używać?

Ta wersja
blog.piotrnalepa.pl/2018/04/22/function-currying-o-co-tu-chodzi-i-jak-tego-uzywac
Opublikowano
Autor
, Staff Software Engineer
Kategoria
JavaScript
Uwagi
Napisz do mnie · Napisz na X

Ten wpis ma 8 lat. Od tego czasu przeglądarki i narzędzia mogły się zmienić, więc zanim użyjesz kodu, sprawdź go z aktualną dokumentacją.

Język JavaScript jest bardzo elastycznym językiem programowania. Z racji tego, że nie jest silnie typowany oraz posiada zaimplementowany mechanizm closures, to możemy tworzyć różne ciekawie napisane funkcje, które będą bardzo elastyczne w swoim działaniu. Jednym z możliwych do osiągnięcia podejść jest podejście zwane function currying.

Sekcja 1Czym jest currying?

Currying jest to proces rozkładania funkcji przyjmującej wiele parametrów do zestawu funkcji które przyjmują tylko jeden argument. Każda pomniejsza funkcja zwraca nową funkcję przyjmującą jeden parametr.

Opis może się wydawać trochę mglisty, więc zilustruję go prostym przykładem:

Przykład 1JavaScript
1
2
3
const add3(a, b, c) => a + b + c;
 
console.log('wynik', add3(1, 2, 3)); // 6

W tym przykładzie stworzono prostą funkcję, która przyjmuje 3 parametry: a, b, c i zwraca sumę tych parametrów (dla uproszczenia, nie sprawdzam czy wartości parametrów posiadają właściwy typ, czyli Number). Jest kilka problemów związanych z tą funkcją:

  • oczekuje zawsze 3 parametry,
  • dobrym zwyczajem jest tworzenie funkcji przyjmujących możliwe jak najmniej parametrów, aby uniknąć zbyt rozbudowanych funkcji,
  • jako że funkcja przyjmuje zawsze 3 parametry, to nie jest możliwe aby użyć tej funkcji tylko z dwoma parametrami lub z większą ilością parametrów niż 3.

Sekcja 2Function currying w praktyce

Na szczęście, można sprawić, że funkcja dodająca kolejne liczby będzie elastyczna i pozwoli na sumowanie dowolnej liczby parametrów zawierających wartości typu Number. W tym celu powstała technika zwana currying.

Przykład 2JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function add(a) {
    let score = a;
 
    const addMore = (b) => {
        score = score + b;
 
        return addMore;
    }
 
    addMore.result = () => score;
 
    return addMore;
};
 
console.log('result:1', add(2)(4).result()); // 6
console.log('result:2', add(2)(4)(6).result()); // 12
console.log('result:3', add(2)(4)(6)(9).result()); // 21

To co się dzieje w kodzie można opisać w sposób następujący:

  1. Tworzymy funkcję add, która przyjmuje parametr a czyli jakąkolwiek liczbę (dla uproszczenia, nie ma sprawdzania typu wartości);
  2. Wartość parametru a jest zapisywana do zmiennej score, która będzie agregatorem wartości kolejnych operacji dodawania;
  3. Wewnątrz funkcji add tworzymy definicję wewnętrznej funkcji addMore, która przyjmuje parametr b. Jej rolą jest sumowanie wartości agregatora score i wartości parametru b, a na koniec zwrócenie referencji do samej siebie.
  4. Z racji tego, że w JS wszystko jest obiektem (nawet funkcje), to korzystam z właściwości języka i dodaję własność o nazwie result, której wartość jest funkcją zwracającą wartość agregatora. Tym samym, w dowolnym momencie możemy sprawdzić wynik sumowania.

Sekcja 3Podsumowanie

W świecie JS, function currying występuje bardzo często. Jednym z najciekawszych przykładów jest sposób integracji komponentu ReactJS ze store'm w Redux, gdy używamy funkcji connect co wygląda podobnie do przykładu:

Przykład 3JavaScript
1
export default connect(mapStateToProps)(App);

Gdzie w pierwszej funkcji przyjmuje mappery jako parametr, a w drugim wywołaniu przyjmuje komponenty ReactJS jako elementy, które mają mieć powiązanie ze store'm w Redux.

Mam nadzieję, że udało mi się przedstawić temat przejrzyście. Zachęcam do komentowania 🙂

Udostępnij
Uwagi

O autorze

Staff Software Engineer

Piszę na tym blogu od 2009 roku, a strony i aplikacje webowe tworzę zawodowo od 14 lat. Obecnie w Bishop Fox prowadzę frontend platformy Cosmos, od samego początku projektu. Wcześniej pracowałem m.in. w OLX, KUDO, Auto1 i eZ Systems. Piszę tu o tym, czego nauczyłem się w praktyce: o JavaScripcie, TypeScripcie, Reakcie, CSS-ie i architekturze frontendu. Występowałem też jako prelegent na konferencjach w Polsce i Europie. Masz pytanie albo pomysł na wpis? Daj znać!