javascript中通过重写tostring和valueof实现无限参数累加柯里化,本质是利用函数对象在隐式转换时自动调用这些方法返回当前和值,需用普通函数而非箭头函数挂载方法。

JavaScript 中通过重写 toString 实现“无限参数累加”的柯里化函数,本质是利用对象在需要字符串或数字上下文(如 + ''、console.log、String())时自动调用 toString(或 valueOf)的特性,让函数既能继续柯里化,又能在被“求值”时返回当前累加结果。
核心原理:函数也是对象,可挂载 toString 方法
在 JavaScript 中,函数是 Function 的实例,属于对象,因此可以像普通对象一样添加属性和方法。我们返回一个函数,同时给它定义 toString(或更健壮地同时定义 valueOf),使其在隐式转换时返回当前和值。
注意:toString 只在字符串上下文中触发(如 '' + add(1)(2)),而 valueOf 优先用于数值运算(如 add(1)(2) + 0)。为兼容性,建议两者都实现,且都返回数字。
基础实现:支持累加 + 隐式转值
以下是一个简洁可靠的实现:
function add(x) {
const fn = function(y) {
return add(x + y);
};
fn.toString = fn.valueOf = () => x;
return fn;
}
使用示例:
-
add(1)(2)(3) + 0→ 6(valueOf被调用) -
'' + add(1)(2)(3)→ "6"(toString被调用) -
console.log(add(1)(2)(3))→ 输出 6(console.log内部会尝试toString) add(1)(2)(3)() // ❌ 不推荐,语义不清,且可能报错(fn 是无参函数,y 为 undefined)
增强版:支持初始无参调用 & 更安全的累加
上面版本要求必须传第一个参数。若想支持 add()()()... 或 add(1)()() 等灵活调用,可改用闭包维护状态,并允许不传参继续柯里化:
function add(x) {
if (x === undefined) return add(0);
const fn = function(y) {
return y === undefined ? fn : add(x + y);
};
fn.toString = fn.valueOf = () => x;
return fn;
}
这样就能写:add(1)(2)(3)() + 0 === 6,末尾空括号只是“触发求值”,不改变结果。但注意:这种空调用不是必须的,纯属风格选择。
注意事项与边界情况
-
不能用于严格相等比较:
add(5) == 5成立(隐式转换),但add(5) === 5为false(类型不同) -
JSON.stringify 无效:
JSON.stringify(add(5))不会调用toString,而是序列化函数本身(通常为"{}"或空字符串) -
避免副作用:不要在
toString里修改状态(如自增计数器),因为它可能被多次、不可预测地调用 -
箭头函数无法直接附加 toString:必须用普通函数(如
function() {...}或const fn = function() {...})才能动态挂载方法
不复杂但容易忽略。关键就三点:返回函数、该函数带 toString 和 valueOf、二者都返回当前累加值。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











