柯里化是函数组合与管道的前提,它将多参函数转为一元函数链,满足组合中“每个函数只接收一个输入”的要求;如curry(format)后可嵌入pipe(trim, toLowerCase, curriedFormat('['](']'))。

JavaScript 中的柯里化本身不直接实现管道或组合,但它为函数组合(compose)和管道(pipe)提供了关键支撑:把多参函数转成一元函数链,从而满足组合链中“每个函数只接收一个输入”的基本要求。
柯里化是组合的前提,不是组合本身
函数组合要求所有参与函数都是一元的(只接收一个参数),否则无法形成数据流。比如:
-
原始函数:
const format = (prefix, str, suffix) => `${prefix}${str}${suffix}`—— 三参数,不能直接进 pipe -
柯里化后:
const curriedFormat = curry(format)→ 可写成curriedFormat('[')('hello')(']'),每一步都返回一元函数 - 此时
curriedFormat('[')(']')就能作为中间环节嵌入 pipe 链,例如:pipe(trim, toLowerCase, curriedFormat('[')(']'))
手写安全的 curry 函数要点
通用 curry 必须适配任意参数个数的函数,并正确处理边界情况:
- 依据
fn.length判断形参个数(注意:箭头函数、带 rest 参数的函数无 reliable length,需额外约定或降级处理) - 每次调用都返回新函数,用闭包缓存已传参数
- 保持
this上下文(使用fn.apply(this, args)而非简单调用) - 支持多次调用传参,如
curry(add)(1, 2)或curry(add)(1)(2)都应生效
const curry = (fn) => {
const curried = (...args) => {
if (args.length >= fn.length) return fn.apply(this, args);
return (...more) => curried(...args, ...more);
};
return curried;
};组合与管道如何与柯里化协同工作
有了柯里化函数,就能自然接入 compose 或 pipe 流程:
立即学习“Java免费学习笔记(深入)”;
-
compose(右到左):
compose(f, g, h)(x)等价于f(g(h(x))),适合数学式表达逻辑(如 selector 层) -
pipe(左到右):
pipe(f, g, h)(x)等价于h(g(f(x))),更贴近阅读顺序,适合数据处理流水线(如表单清洗) - 柯里化函数可提前固化部分参数,例如:
const safeParseInt = curry(parseInt)(10),之后可直接用于 pipe:pipe(safeParseInt, x => x * 2) - 异步场景下,可扩展 pipe 支持 Promise:用
await替代同步fn(acc),使asyncPipe能混搭普通函数与 async 函数
实际业务中的典型链条
以用户输入处理为例,组合 + 柯里化让逻辑清晰又可复用:
- 定义纯函数:
const trim = s => s?.trim() || '',const toLower = s => s.toLowerCase(),const pad = curry((len, char, s) => s.padStart(len, char)) - 构建管道:
const normalize = pipe(trim, toLower, pad(5)('0')) - 调用:
normalize(' 42 ')→'00042' - 后续还可复用
pad(5)('0')或pad(8)('x')到其他流程中


















