JavaScript函数柯里化依据fn.length(非默认、非rest形参个数)判断是否继续接收参数:若已传参数数小于length则返回新函数,否则执行原函数;需用闭包保存参数、正确绑定this并合并参数。

JavaScript 中函数柯里化利用 length 属性判断剩余未传参数,本质是依靠函数定义时形参个数(即 fn.length)与当前已传入实参个数的差值,来决定是否继续返回新函数还是执行原函数。
length 属性只反映形参个数,不包括 rest 参数
Function.prototype.length 返回函数声明中**非默认、非 rest 的形参个数**。例如:
function f(a, b, c) {} // f.length === 3
function g(a, b = 1, c) {} // g.length === 1(遇到第一个默认参数就停止计数)
function h(a, ...rest) {} // h.length === 1(rest 参数不计入)
function i() {} // i.length === 0
因此,柯里化实现必须基于这个“预期总参数数”,不能依赖调用时的 arguments.length 或展开后的实际数量。
基础柯里化逻辑:用已传参数个数对比 length
每次调用柯里化函数时,收集当前传入的参数;若已传参数个数 小于 原函数的 length,就返回一个新函数等待更多参数;否则立即执行原函数。
- 用闭包保存已传参数(如
argsSoFar) - 新函数接收新参数(
...newArgs),合并后检查总数:argsSoFar.concat(newArgs).length - 满足条件则递归返回柯里化函数;否则用
fn.apply(this, mergedArgs)执行
注意 this 绑定和参数合并方式
直接用 Array.prototype.concat 合并参数简单可靠;但需确保调用时的 this 正确传递(尤其在对象方法柯里化场景):
- 返回的新函数应使用
fn.call(this, ...mergedArgs)而非apply确保 this 不丢失 - 若用箭头函数实现柯里化器,会丢失原始 this,应避免
- ES6+ 推荐用扩展运算符:
[...argsSoFar, ...newArgs]替代 concat
一个可运行的简易实现
以下是一个仅依赖 length 判断的轻量柯里化函数:
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.concat(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
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











