JavaScript函数柯里化求和的核心是通过闭包累积参数并延迟执行,支持链式调用任意次,通过valueOf/toString隐式转数值或end()显式获取结果。

JavaScript中函数柯里化实现多参数求和,核心是让一个接收多个参数的函数,变成可以逐个或分批传参、延迟执行的形式。关键不在于硬编码几个参数,而在于支持任意数量参数的累积与自动触发求和——当参数足够(或显式调用)时才计算结果。
基础柯里化求和:固定参数个数
若明确需要 3 个数相加,可写成:
const sum3 = a => b => c => a + b + c; console.log(sum3(1)(2)(3)); // 6
但这种写法无法处理 2 个、4 个或更多参数,也不通用。
动态参数累积:用闭包保存中间值
真正通用的柯里化求和,应支持链式调用任意次,并在无新参数传入时返回结果。常见做法是返回一个函数,它既能继续接收参数,也能作为数字被使用(通过 valueOf 或 toString):
- 每次调用都返回新函数,同时把新参数累加到内部和中
- 重写 valueOf(),让 JS 在需要数值时自动触发求值
- 保持函数可继续调用(支持
sum(1)(2)(3)),也可立即取值(+sum(1)(2)(3)或sum(1)(2)(3) + 0)
function sum(a) {
let total = a;
function curried(b) {
if (b === undefined) return total;
total += b;
return curried;
}
curried.valueOf = () => total;
curried.toString = () => String(total);
return curried;
}
console.log(+sum(1)(2)(3)); // 6
console.log(sum(1)(2)(3) + 10); // 16
console.log(sum(5)()); // 5(显式结束)
更健壮的通用模板:支持初始空调用与数组展开
进一步增强实用性,可允许首次调用不传参(返回 0),并兼容单次传入数组:
- 用 arguments 或 rest 参数收集每次传入的值
- 判断是否为函数调用上下文(而非数值运算),决定是否继续柯里化
- 提供 .end() 方法显式结束并返回结果,避免隐式转换歧义
function sum(...args) {
let total = args.reduce((a, b) => a + b, 0);
function curried(...newArgs) {
if (newArgs.length === 0) return total;
total += newArgs.reduce((a, b) => a + b, 0);
return curried;
}
curried.valueOf = () => total;
curried.toString = () => String(total);
curried.end = () => total;
return curried;
}
// 使用示例:
console.log(sum(1)(2)(3).end()); // 6
console.log(+sum(1, 2)(3, 4)); // 10
console.log(sum()(1)(2, 3).end()); // 6
注意事项与边界情况
实际使用需注意:
- 不要依赖 valueOf/toString 在所有上下文中都自动触发(如 JSON.stringify 不会调用它们)
- 若需序列化或调试,建议显式调用 .end() 或 Number(curried)
- NaN 或非数字参数会导致 total 变为 NaN,建议增加类型校验(如
typeof b === 'number') - 该模式本质是闭包 + 函数复用,无需 new 或 bind,轻量但要注意内存中闭包引用
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











