javascript函数柯里化本质是利用闭包保存已传参数,通过递归分步收集参数并判断是否达到fn.length,不足则返回新函数继续接收,齐备则用fn.apply(this, args)执行原函数。

JavaScript 函数柯里化通过递归分步传递参数,本质是利用闭包保存已传入的参数,并在每次调用时判断是否凑够原函数所需的全部参数;没凑够就返回新函数继续接收,凑够了就执行原函数。关键在于“收集—判断—递归/执行”这个闭环逻辑。
递归触发条件:参数不足时自动返回新函数
每次调用柯里化后的函数,都会把新参数追加进已收集的参数数组。若当前总参数个数仍小于 fn.length(即原函数声明的形参个数),就递归调用自身,把已收集的参数传进去,再返回一个等待下一轮参数的函数。
- 用
Array.prototype.concat或展开运算符合并新旧参数 - 递归调用时保持
this上下文一致(常用call(this, ...)) - 避免直接修改原始参数数组,防止多次调用互相干扰
参数收集方式:支持单个或多个参数混入
健壮的柯里化实现不强制每次只传一个参数。比如 curry(add)(1,2)(3) 和 curry(add)(1)(2)(3) 都应正确工作。这就要求内部用 arguments 或 rest 参数统一提取,再拼接到历史参数中。
- 用
[...arguments]获取本次所有实参 - 用
newArgs = [...oldArgs, ...currentArgs]合并 - 合并后立即检查
newArgs.length >= fn.length
终止递归:参数齐备时执行原函数
一旦累计参数数量达到或超过 fn.length,就停止递归,用 fn.apply(this, newArgs) 执行原函数。注意这里通常只取前 fn.length 个参数,避免多余参数干扰结果。
- 执行后不重置收集数组,除非明确需要支持重复调用(如 lodash 的 curry)
- 若需支持多次独立调用,可在执行前用
newArgs.slice(0, fn.length)截断 - 返回值就是原函数的执行结果,不是新函数
一个可运行的递归柯里化示例
下面这段代码能处理 fn(1)(2,3)、fn(1,2)(3) 等任意分组方式:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return function(...moreArgs) {
return curried.apply(this, [...args, ...moreArgs]);
};
};
}
它用 ES6 的 rest 参数简化了参数处理,递归调用 curried 本身,形成清晰的“收参→比对→再收或执行”链条。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











