Composición de funciones en JavaScript

La composición de funciones es la aplicación puntual de una función al resultado de otra. Los desarrolladores lo hacen de manera manual todos los días cuando el nido funciona:

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

Pero esto es difícil de leer. Existe una forma mejor de utilizar la composición de funciones. En lugar de leerlos de adentro hacia afuera:

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

Podemos usar una función de orden superior para encadenarlos de forma ordenada.

add2AndSquare = compose( add2, square)

Una implementación simple de componer sería:

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

Para obtener aún más flexibilidad, podemos usar la función reduceRight:

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

Leer redactar de izquierda a derecha permite un encadenamiento claro de funciones de orden superior. Los ejemplos del mundo real son la adición de autenticaciones, registros y propiedades de contexto. Es una técnica que permite la reutilización al más alto nivel. A continuación, se muestran algunos ejemplos de cómo utilizarlo:

// 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

Puede pensar que se trata de una programación funcional avanzada y no es relevante para la programación frontend. Pero también es útil en aplicaciones de una sola página. Por ejemplo, puede agregar comportamiento a un componente de React utilizando componentes de orden 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);

En conclusión, la composición de funciones permite la reutilización de la funcionalidad a un nivel muy alto. Si las funciones están bien estructuradas, permite a los desarrolladores crear un nuevo comportamiento basado en el comportamiento existente.

También aumenta la legibilidad de las implementaciones. En lugar de anidar funciones, puede encadenar claramente funciones y crear funciones de orden superior con nombres significativos.