Composición de funciones con función de orden superior en JavaScript

Dec 04 2022
En este artículo, intentemos comprender cómo podemos crear funcionalidades complejas al componer funciones más pequeñas en JavaScript. COMER, DORMIR, CODIFICAR: enfoque anidado Supongamos que queremos realizar la actividad "COMER, DORMIR, CODIFICAR" y repetirla de nuevo.
Foto de Kelly Sikkema en Unsplash

En este artículo, intentemos comprender cómo podemos crear funcionalidades complejas al componer funciones más pequeñas en JavaScript.

COMER, DORMIR, CODIFICAR — Enfoque anidado

Supongamos que queremos realizar la actividad “COMER, DORMIR, CODIFICAR” y repetir esto nuevamente. Aquí hay un enfoque de cómo podríamos hacer esto.

const activity = (str) => str.toUpperCase();
const sleep = (str) => `${str} SLEEP`;
const code = (str) => `${str} CODE`;
const repeat = (str) => `${str} | ${str}`;

// EAT SLEEP CODE | EAT SLEEP CODE
console.log(
  repeat(code(sleep(activity('eat'))))
  );

COMER, DORMIR, CÓDIGO — Composición de orden superior

Veremos cómo podríamos mejorar esto usando una función de orden superior que crearía una composición para nosotros.

const activity = (str) => str.toUpperCase();
const sleep = (str) => `${str} SLEEP`;
const code = (str) => `${str} CODE`;
const repeat = (str) => `${str} | ${str}`;

// Higher order function that accepts any number of functions as arguments
const compose = (...fns) => x => fns.reduce((acc, fn)=> fn(acc),x);
const myRoutine = compose(activity, sleep, code, repeat);

// EAT SLEEP CODE | EAT SLEEP CODE
console.log(myRoutine('eat'));

  • El método componer puede aceptar múltiples funciones como argumentos usando un operador de descanso.
  • Luego devuelve una función que está esperando su valor inicial.
  • Dentro de esta función devuelta, podemos acceder a la matriz de funciones que se pasaron como argumento (cierre).
  • El orden de la función va de izquierda a derecha. Así que usaremos el método reduce, que acepta un acumulador y el valor actual que es una función. Esto devolverá el resultado del valor acumulado en la función actual.
  • El segundo argumento para reducir es nuestro valor inicial x.
  • Entonces finalmente podemos crear nuestra rutina componiendo todas nuestras actividades. La rutina debe invocarse pasando el argumento de la primera función.

Aquí está la vista desglosada de la función de redacción para una mayor claridad.


// Arrow variant
const compose = (...fns) => x => fns.reduce((acc, fn)=> fn(acc),x);

// Non arrow variant
function compose(...fns) {
  return function (x) {
    return fns.reduce((acc, fn) => fn(acc), x);
  };
}

Este enfoque tiene los siguientes beneficios:

  • Ayuda a reducir las molestias causadas por anidar múltiples funciones.
  • Legible y escalable