JavaScript柯里化加法累加器通过闭包维护sum,支持链式调用与隐式求值(toString/valueOf),可扩展为无参终止、多参数输入,但需注意浮点精度、类型校验及不可重用性。

JavaScript 中用柯里化实现通用加法累加器,核心是让函数能接收一个或多个数字,每次调用返回新函数,直到被显式求值(比如调用 () 或转为原始值),再执行累加。关键在于:**保持状态、延迟计算、支持链式调用、兼容隐式转换**。
基础柯里化累加器(支持无限参数 + 隐式求值)
最实用的写法是利用函数对象属性 + toString/valueOf 实现自动触发求值:
- 函数本身作为累加器闭包,内部维护总和
sum - 每次调用返回自身,并把新参数加到
sum上 - 重写
toString和valueOf,让console.log、+ ''、==等场景自动返回当前和
示例代码:
function add(x) {
let sum = x;
function curried(y) {
sum += y;
return curried;
}
curried.toString = curried.valueOf = () => sum;
return curried;
}
// 使用:
add(1)(2)(3); // → 6(隐式调用 toString)
add(1)(2)(3) + ''; // → "6"
+add(1)(2)(3); // → 6
console.log(add(5)(10)(15)); // → 30
支持无参调用结束(更明确的终止方式)
有些场景希望“不传参就返回结果”,即 add(1)(2)() 显式收尾。这时需判断参数个数:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 若调用时无参数(
y === undefined),直接返回当前和 - 否则继续累加并返回函数
注意:此时无法靠 toString 自动触发,必须显式调用 () 或 .valueOf():
function add(x) {
let sum = x;
function curried(y) {
if (y === undefined) return sum;
sum += y;
return curried;
}
return curried;
}
// 使用:
add(1)(2)(3)(); // → 6
add(10)(20)(); // → 30
add(1)(2)(3).valueOf(); // → 6
支持单次传多个数(增强灵活性)
实际中常希望 add(1, 2, 3) 或 add(1)(2, 3) 都能工作。只需让内部处理可变参数:
- 用
...args接收所有参数,逐个累加 - 仍返回自身,保持柯里化链
- 同时保留无参调用或
toString触发能力
改进版:
function add(...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 = curried.valueOf = () => sum;
return curried;
}
// 使用:
add(1)(2, 3)(4)(); // → 10
add(1, 2)(3)(4, 5); // → 15(隐式)
注意事项与边界情况
这类累加器看似简洁,但要注意几个易错点:
-
浮点数精度:JS 浮点运算固有误差,如
add(0.1)(0.2)得0.30000000000000004,业务中需考虑toFixed或整数放大 -
非数字输入:未做类型校验,
add('1')('2')会变成字符串拼接('12')。如需健壮,应提前Number(y)转换并检查isNaN -
不可重用性:每个
add(x)返回独立闭包,互不影响;但同一累加器多次调用会持续累加,不是“新建实例” -
JSON 序列化失效:函数不能被
JSON.stringify,若需持久化,得额外提供.value()方法

















