JavaScript柯里化求和函数通过闭包维护累加状态,支持传参累积与空参触发求值,并利用toString/valueOf实现隐式转换以支持链式调用和数值运算。

JavaScript 中函数柯里化处理不定数量参数的动态累加求和,核心在于让函数既能接收部分参数并返回新函数,又能在“被调用时无参数”或“显式触发求值”时返回最终结果。关键不是强行支持任意次无参调用,而是设计一个可中断、可累积、有明确结束信号的柯里化求和函数。
用闭包保存累加状态,靠空参/特殊调用触发计算
标准柯里化是固定参数个数,但求和天然需要不定长。常见解法是:每次传参都累加,不立即返回结果;当以 () 形式被调用(即无参数)时,返回当前总和,并重置或保持可继续累加的能力。
- 利用闭包维护一个内部 sum 变量
- 返回的函数本身可被再次调用(接收数字),也可被直接调用(
sum())来获取结果 - 为支持链式调用,返回的函数可以同时是函数又是数值(通过
toString/valueOf隐式转换)
实现一:支持 () 触发求值 + 链式调用(推荐)
这是最实用、语义清晰的方式:
function currySum(a) {
let sum = a ?? 0;
function curried(b) {
if (b === undefined) return sum; // 无参调用 → 返回结果
sum += b;
return curried;
}
// 支持隐式转字符串/数字(如 console.log(sum(1)(2)) 或 +sum(1)(2))
curried.toString = () => String(sum);
curried.valueOf = () => sum;
return curried;
}
// 使用示例:
currySum(1)(2)(3)(); // 6
currySum(5)(10)(20); // 仍是函数,但 + 运算会触发 valueOf → 35
console.log(currySum(1)(2)(3)); // "6"(toString 起作用)
console.log(+currySum(1)(2)(3)); // 6(valueOf 起作用)
实现二:支持传入数组或多个参数(更灵活)
如果希望一次传多个数(如 sum(1,2,3)(4,5)()),可扩展参数接收逻辑:
立即学习“Java免费学习笔记(深入)”;
function currySum(...args) {
let sum = args.reduce((a, b) => a + b, 0);
function curried(...moreArgs) {
if (moreArgs.length === 0) return sum;
sum += moreArgs.reduce((a, b) => a + b, 0);
return curried;
}
curried.toString = () => String(sum);
curried.valueOf = () => sum;
return curried;
}
// 使用:
currySum(1, 2)(3, 4, 5)(); // 15
currySum()(1)(2,3)(4)(); // 10(支持初始无参)
注意事项与边界处理
实际使用中需注意几个细节:
-
非数字参数应忽略或报错:可在累加前用
Number(b)转换,或isNaN过滤 -
避免意外的隐式转换副作用:比如
currySum({})('1')可能产生 NaN,建议增加类型校验 -
重置能力(可选):若需多次独立使用,可暴露
.reset()方法或返回带 reset 的对象 -
不适用于严格相等比较:因为返回的是函数,
currySum(5) === 5为 false,必须用==或显式调用()


















