柯里化是利用闭包将多参数函数拆为一系列单参数函数,每次传一个参数并返回新函数,直至参数集齐才执行原逻辑;闭包确保已传参数安全存储于私有作用域中。

柯里化本质上就是利用闭包把多参数函数拆成一系列单参数函数,每次调用只传一个参数,返回一个新函数等待后续参数,最终累积够了才执行原逻辑。
闭包是柯里化的底层支撑
闭包让内部函数能记住外层函数的参数和变量,这些“已传入但未执行”的参数被安全地保存在私有作用域中,不会污染全局,也不会被垃圾回收。
比如原始函数 add(a, b, c),柯里化后变成 add(1)(2)(3),其中 add(1) 返回的函数记住了 a = 1,add(1)(2) 返回的函数又记住了 b = 2,直到第三个参数进来才真正计算 1 + 2 + 3。
手写通用柯里化函数(基于闭包)
核心思路:用闭包缓存已传参数,通过递归或参数长度判断是否该执行原函数。
立即学习“Java免费学习笔记(深入)”;
- 检查当前收集的参数个数是否等于原函数期望的参数数量(
fn.length) - 没集齐就返回新函数,继续用闭包保存已有参数
- 集齐就用
fn.apply执行,并清空缓存
示例:
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));
};
};
}
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6
console.log(curriedAdd(1)(2, 3)); // 6
实际使用中的简化技巧
不必每次都手写 curry,可封装常用场景,让调用更直观:
- 固定前几个参数:比如
const add10 = curry(add)(10),之后直接add10(5)(3)得 18 - 配合函数式工具库(如 Lodash 的
_.curry),自动处理 this 绑定和占位符 - 与高阶函数组合:比如
map(curriedAdd(1))把数组每个元素加 1,无需写匿名函数
注意闭包带来的常见问题
闭包本身不是黑魔法,但需留意两点:
- 参数缓存是按调用链独立的:每次初始调用(如
curriedAdd(1))都生成新的闭包环境,互不影响 - 不要在循环中直接创建柯里化函数并立即执行,容易因闭包捕获的是循环变量引用而出错(可用 IIFE 或 let 解决)
柯里化不是为炫技,而是让函数更灵活、可复用、易组合。闭包在这里不是额外负担,而是让这种“分步传参”变得自然可靠的必要机制。


















