JavaScript实现无需末尾空调用的柯里化不定参数sum求和函数
实现无末尾空参的无限柯里化sum函数
核心前提说明
首先明确JavaScript的语法限制:如果完全不依赖类型转换机制,不存在能100%满足需求的实现。
原因很简单:只要你需要支持sum(1)(2)(3)这种连续括号调用的形式,每一次函数执行的返回值就必须是可调用的函数类型,而函数属于引用类型,没有任何语法可以让一个引用类型值在不触发类型转换的前提下,直接被当作数字类型输出、参与运算。
你提到的valueOf方案本质就是利用了JS的类型转换机制,只是单独使用valueOf的兼容性和覆盖场景不全,我们可以通过搭配Symbol.toPrimitive和toString补全所有转换场景,实现接近完美的使用效果。
完整实现代码
function sum(...args) { // 累加当前所有传入参数的总和 const currentTotal = args.reduce((pre, cur) => pre + cur, 0) // 返回支持继续链式调用的函数 const chainedFn = (...newArgs) => sum(currentTotal, ...newArgs) // 配置所有原始值转换逻辑,覆盖所有取值场景 chainedFn[Symbol.toPrimitive] = () => currentTotal chainedFn.valueOf = () => currentTotal chainedFn.toString = () => String(currentTotal) return chainedFn }
效果验证
// 匹配示例需求 console.log("output should be: ", sum(1)(2,3)(4,5,6)) // 输出: output should be: 21 // 支持直接参与数学运算 console.log(sum(1,2)(3) + 10) // 输出: 16 console.log(sum(5)(5)(5) * 2) // 输出: 30 // 支持比较运算 console.log(sum(1)(2)(3) == 6) // 输出: true
方案说明
- 这个实现覆盖了绝大多数实际业务使用场景,只要返回值被当作原始值使用(输出、运算、比较),都会自动拿到正确的累加结果
- 末尾空参调用的方案本质是通过判断入参是否为空来切换返回值类型(返回函数/返回数字),缺点是必须额外传一次空括号触发返回逻辑,和类型转换方案是两种不同的实现思路,可根据场景选择
- 不存在完全脱离类型转换的实现,这是JS本身的语法特性决定的,没有黑科技可以绕过这个限制。
内容的提问来源于stack exchange,提问作者Kishor
相关产品推荐
相关产品推荐

