柯里化是将多参数函数拆为单参数函数链,支持分批传参并自动等待参数齐备才执行;其核心在于参数计数与闭包暂存,而非单纯嵌套函数。

柯里化不是“把函数变短”,而是把多参数函数拆成一系列单参数函数调用;它本身不提升性能,但能增强组合性与复用粒度——这点常被初学者误读。
什么是 curry?看一个典型错误理解
很多人以为 curry((a, b, c) => a + b + c) 返回的是 (a) => (b) => (c) => a + b + c 就算完成。其实漏了关键点:柯里化必须支持**参数分批传入、自动等待参数齐备才执行**。
- 错例:
curry(add3)(1)(2)(3)能跑,但curry(add3)(1, 2)(3)或curry(add3)(1)(2, 3)报错 → 不是真柯里化 - 对的做法:内部需记录已传参数个数,用闭包暂存,直到累计够原函数的
length - 注意:
function.length只反映形参个数(不含 rest 参数),遇到(a, b, ...rest)时会失准
手写一个健壮的 curry 函数
核心逻辑是递归绑定 + 参数收集,不依赖外部库也能控制行为边界:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return function (...nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
};
}
- 它支持任意调用风格:
add(1)(2, 3)、add(1, 2)(3)、add(1)(2)(3)全部有效 -
this绑定靠apply保留,避免箭头函数导致上下文丢失 - 不处理 rest 参数场景;如需兼容,得改用
fn.toString()解析或显式传入期望参数数
函数式编程在 JS 中的真实优势,不是“看起来高级”
优势体现在具体协作场景中,而非抽象理念:
立即学习“Java免费学习笔记(深入)”;
- 可预测性:纯函数 + 不可变数据 → 同输入必得同输出,调试时不用查“谁改了 state”
-
测试友好:一个
map+filter链,可逐层 mock 输入验证每步输出,不用启整个 React 组件树 -
组合自由:比如
compose(formatDate, truncate(20), capitalize)比写三个嵌套if更易维护 - 并发安全:没有共享可变状态,Web Worker 里跑数据转换逻辑天然无锁
柯里化真正难的不是实现,是判断什么时候该用——比如 fetch 封装成 curry((baseUrl, path, options) => ...) 确实方便复用,但若每次都要动态拼 baseUrl,反而增加调用方心智负担。边界感比语法更重要。











