支持多阶段调用的函数柯里化器通过闭包累积参数,仅当参数总数≥fn.length时执行原函数,否则返回可继续调用的新函数;支持批量传参、链式调用、占位符及.done()手动触发。

实现支持多阶段调用的函数柯里化器,核心在于:每次传入部分参数后返回一个新函数,该函数能累积已有参数,并在参数足够时自动执行原函数;同时允许随时补全剩余参数,也支持提前终止并获取当前“冻结”的柯里化函数。
基础逻辑:参数累积与惰性求值
柯里化不是简单地固定前几个参数,而是构建一个可延续的调用链。关键点包括:
- 记录已传入的参数(用闭包保存)
- 每次调用时,合并新参数,不立即执行原函数
- 仅当累积参数数量 ≥ 原函数期望的形参个数(fn.length)时,才触发执行
- 若参数不足,返回一个新的柯里化函数,等待下一次调用
支持不定长调用的灵活设计
真实场景中,用户可能分多次传参(如 curry(add)(1)(2)(3) 或 curry(add)(1, 2)(3)),因此需支持“多参数批量传入”和“单参数链式调用”混合使用:
- 内部用数组累积所有已传参数:
const args = [] - 每次调用时,用
[...args, ...newArgs]合并 - 不依赖调用次数,只看总参数长度是否达标
- 返回的函数自身也具备柯里化能力(即返回的函数可继续被调用)
实现示例(ES6 简洁版)
以下是一个生产可用的轻量实现:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn(...args);
}
return (...moreArgs) => curried(...args, ...moreArgs);
};
}
用法示例:
const add = (a, b, c) => a + b + c; const curriedAdd = curry(add); curriedAdd(1)(2)(3); // 6 curriedAdd(1, 2)(3); // 6 curriedAdd(1)(2, 3); // 6 curriedAdd(1, 2, 3); // 6
进阶:支持占位符与手动触发
为提升实用性,可加入占位符(如 _)跳过某位置,或提供 .done() 显式执行:
- 定义全局占位符常量(如
const __ = Symbol('placeholder')) - 累积参数时,遇占位符不计入有效长度,但保留位置
- 返回的柯里化函数挂载
done方法,强制以当前参数执行(即使未满) - 也可支持
toString()/valueOf()隐式转换,用于模板字符串或数值运算上下文
不复杂但容易忽略细节:形参长度 fn.length 只反映非默认、非解构、非剩余参数的声明个数;若需兼容带默认值的函数,应改用显式指定 arity(如 curry(fn, 3))。











