Estructura tu código con currying, composición de funciones y datos inmutables para ganar previsibilidad y testabilidad.
Abrir esta lección en KodokonJavaScript trata las funciones como valores de primera clase, lo que abre la puerta a los patrones funcionales. El currying convierte una función de n argumentos en una cadena de funciones de un solo argumento: f(a, b, c) se convierte en f(a)(b)(c). No hay que confundirlo con la aplicación parcial, que fija algunos argumentos en un solo paso (fn.bind(null, a)). El currying brilla al crear funciones especializadas a partir de otras genéricas.
const curry = (fn) => {
const arity = fn.length;
return function curried(...args) {
if (args.length >= arity) return fn(...args);
return (...rest) => curried(...args, ...rest);
};
};
const add3 = (a, b, c) => a + b + c;
const addCurried = curry(add3);
console.log(addCurried(1)(2)(3)); // 6
console.log(addCurried(1, 2)(3)); // 6Una sutileza de la especificación: fn.length solo cuenta los parámetros situados antes del primer parámetro por defecto o rest. (a, b = 1) => {} tiene una longitud de 1, (...args) => {} de 0. Por lo tanto, a un curry basado en la aridad hay que darle funciones con parámetros simples. La composición es el siguiente paso: ensamblar pequeñas funciones puras en tuberías legibles.
const pipe = (...fns) => (input) =>
fns.reduce((acc, fn) => fn(acc), input);
const trim = (s) => s.trim();
const lower = (s) => s.toLowerCase();
const dashes = (s) => s.replace(/\s+/g, "-");
const toSlug = pipe(trim, lower, dashes);
console.log(toSlug(" Hello World "));
// "hello-world"pipe(f, g, h)(x) calcula h(g(f(x))): lo lees en orden de ejecución. La variante compose aplica de derecha a izquierda, como la notación matemática. Estas tuberías solo tienen valor si las funciones son puras - sin efectos secundarios, sin dependencias ocultas - lo que exige datos inmutables: en lugar de mutar un objeto, produces una nueva versión de él, y la igualdad por referencia basta entonces para detectar un cambio (el corazón de la reconciliación de React).
const state = Object.freeze({
user: { name: "Ada" },
tags: ["js"]
});
const next = {
...state,
tags: [...state.tags, "fp"]
};
const deepCopy = structuredClone(state);
deepCopy.user.name = "Grace"; // independent copybind, el currying solo con funciones flechapipe(f, g, h)(x)?const s = Object.freeze({ a: { b: 1 } }), ¿funciona la asignación s.a.b = 2?s.a no está congelado