Compoziția funcției este aplicarea punctuală a unei funcții la rezultatul alteia. Dezvoltatorii o fac manual în fiecare zi, când funcționează cuibul:

compose = (fn1, fn2) => value => fn2(fn1(value))

Dar acest lucru este greu de citit. Există o modalitate mai bună de a utiliza compoziția funcției. În loc să le citiți din interior spre exterior:

add2AndSquare = (n) => square(add2(n))

Putem folosi o funcție de ordine superioară pentru a le înlănți într-un mod ordonat.

add2AndSquare = compose( add2, square)

O simplă implementare a compose ar fi:

compose = (f1, f2) => value => f2( f1(value) );

Pentru a obține și mai multă flexibilitate, putem utiliza funcția reduceRight:

compose = (...fns) => (initialVal) => fns.reduceRight((val, fn) => fn(val), initialVal);

Citirea compunerii de la stânga la dreapta permite o înlănțuire clară a funcțiilor de ordin superior. Exemple din lumea reală sunt adăugarea de autentificări, înregistrare și proprietăți de context. Este o tehnică care permite reutilizarea la cel mai înalt nivel. Iată câteva exemple de utilizare:

// example
const add2        = (n) => n + 2;
const times2      = (n) => n * 2;
const times2add2  = compose(add2, times2);
const add6        = compose(add2, add2, add2);

times2add2(2);  // 6
add2tiems2(2);  // 8
add6(2);        // 8

Ați putea crede că aceasta este o programare funcțională avansată și nu este relevantă pentru programarea frontend. Dar este util și în aplicațiile cu o singură pagină. De exemplu, puteți adăuga comportament la o componentă React utilizând componente de ordin superior:

function logProps(InputComponent) {
  InputComponent.prototype.componentWillReceiveProps = function(nextProps) {
    console.log('Current props: ', this.props);
    console.log('Next props: ', nextProps);
  };
  return InputComponent;
}

// EnhancedComponent will log whenever props are received
const EnhancedComponent = logProps(InputComponent);

În concluzie, compoziția funcției permite reutilizarea funcționalității la un nivel foarte ridicat. Dacă funcțiile sunt bine structurate, acesta permite dezvoltatorilor să creeze un comportament nou pe baza comportamentului existent.

De asemenea, crește lizibilitatea implementărilor. În loc de funcții de cuibărire, puteți înlătura în mod clar funcții și puteți crea funcții de ordin superior cu nume semnificative.