Javi Moreno
Funciones de Orden Superior en JavaScript: De lo Básico a lo Avanzado

Funciones de Orden Superior en JavaScript: De lo Básico a lo Avanzado

En JavaScript, las funciones son ciudadanos de primera clase (first-class citizens). Esto permite tratarlas como valores: asignarlas a variables, pasarlas como argumentos y devolverlas desde otras funciones.
Una función de orden superior (HOF) es, precisamente, una función que recibe funciones como parámetros, devuelve funciones, o ambas.


🤔 ¿Qué son y por qué se usan?

Definición: Una HOF es una función que opera sobre funciones: las acepta o las produce.
Motivación:

  • Abstraer patrones y generalizar comportamiento.
  • Reutilizar y componer lógica de forma declarativa.
  • Aislar efectos secundarios y mejorar la testeabilidad.

🧪 Ejemplos básicos

1) Pasar funciones como argumento

function aplicar(a, b, operacion) {
  return operacion(a, b);
}
const sumar = (x, y) => x + y;
const multiplicar = (x, y) => x * y;

aplicar(3, 4, sumar);        // 7
aplicar(3, 4, multiplicar);  // 12

2) Devolver funciones (closures)

function crearMultiplicador(n) {
  return function(x) {
    return x * n;
  };
}
const duplicar = crearMultiplicador(2);
duplicar(5); // 10

3) HOFs del core de arrays: map, filter, reduce

const nums = [1, 2, 3, 4, 5];

nums.map(n => n * 2);                // [2, 4, 6, 8, 10]
nums.filter(n => n % 2 === 0);       // [2, 4]
nums.reduce((acc, n) => acc + n, 0); // 15

🧩 Composición de funciones

La composición encadena funciones pequeñas para crear transformaciones más potentes.

// compose(f, g)(x) = f(g(x))
const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);
// pipe(g, f)(x) = f(g(x)) pero de izquierda a derecha
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);

const trim = (s) => s.trim();
const toUpper = (s) => s.toUpperCase();
const exclaim = (s) => s + "!";

const limpiarYEnfatizar = pipe(trim, toUpper, exclaim);
limpiarYEnfatizar("  hola  "); // "HOLA!"

📈 ¿Cuándo son mejores las HOFs?

  • Transformaciones de colecciones y pipelines de datos.
  • Configuración y cross-cutting concerns (logging, permisos, caching).
  • APIs declarativas en UI (React Hooks/props como funciones) y middleware.
  • Control de flujo asíncrono (reintentos, backoff, debounce/throttle).

⚠️ Posibles inconvenientes

  • Sobreabstracción: demasiadas capas ocultan la intención.
  • Legibilidad: composición excesiva puede complicar el seguimiento.
  • Rendimiento: en hot paths, demasiados closures/callbacks pueden penalizar.
  • Depuración: stacks más profundos; nombra funciones cuando sea posible.

📚 Fuentes y lecturas recomendadas