JavaScript中实现无限参数累加的柯里化函数,核心是利用valueOf和toString实现隐式类型转换:每次调用返回新函数并累积参数,同时挂载toString/valueOf返回当前和值,从而支持console.log、+运算等自动求值。

JavaScript 中实现支持无限参数累加的柯里化函数,核心在于让函数既能接收部分参数并返回新函数,又能在被当作普通值使用(比如被 console.log、+ 运算或 Number() 调用)时自动求值。这需要利用函数对象的隐式类型转换机制。
利用 toString 和 valueOf 实现自动求值
JavaScript 在需要将函数转为原始值(如字符串拼接、数值运算)时,会优先调用 valueOf(期望返回基本类型),若未定义或返回非原始值,则 fallback 到 toString。我们正是靠这个特性让柯里化函数“看起来像一个数”。
实现要点:
- 每次调用都返回一个新函数,内部累积参数
- 给返回的函数挂载
toString(和可选的valueOf),使其返回当前累加结果 - 确保多次调用仍保持累加状态(闭包维护 sum)
基础版本:支持数字累加的无限柯里化
下面是一个简洁可靠的实现:
立即学习“Java免费学习笔记(深入)”;
function add(...args) {
let sum = args.reduce((a, b) => a + b, 0);
const curried = function(...nextArgs) {
sum += nextArgs.reduce((a, b) => a + b, 0);
return curried;
};
curried.toString = () => sum;
curried.valueOf = () => sum;
return curried;
}
用法示例:
console.log(add(1)(2)(3)); // 6(隐式调用 toString) console.log(add(1, 2)(3, 4)); // 10 console.log(+add(5)(10)(15)); // 30(+ 触发 valueOf) console.log(add(1)(2)(3) + 4); // 10(+ 触发 valueOf 或 toString)
增强版:支持重置与显式求值方法
如果希望更可控,可以添加 .value() 方法,并支持链式调用后清空状态(按需):
function add(...args) {
let sum = args.reduce((a, b) => a + b, 0);
const curried = function(...nextArgs) {
sum += nextArgs.reduce((a, b) => a + b, 0);
return curried;
};
curried.value = () => sum;
curried.toString = () => String(sum);
curried.valueOf = () => sum;
return curried;
}
这样你可以显式写 add(1)(2)(3).value() 得到 6,也兼容隐式转换。
注意事项与边界情况
这类函数在实际工程中要谨慎使用:
- 不能直接 JSON.stringify(会变成
"[object Function]"),因为toString不影响序列化逻辑 - 不适用于需要严格区分函数和数值的场景(比如某些类型检查库)
- 若传入非数字参数(如字符串
'2'),会触发隐式转换,可能产生意外结果(add(1)('2')→12);如需健壮性,应提前校验或统一转Number - 箭头函数无法动态设置
toString,必须用传统 function 表达式
不复杂但容易忽略。


















