JavaScript动态求和柯里化依据函数length自动触发计算,支持多参数组合、占位符及链式调用,无需额外调用或手动维护参数数组。

JavaScript 动态求和中使用柯里化,核心是把“等参数凑够再算”变成自然行为,而不是手动计数或拼数组。它不依赖调用次数,而是依据函数原本需要几个参数(fn.length)自动判断是否该执行求和。
按形参个数自动触发计算
标准柯里化求和函数会读取原函数的 length 属性——比如 sum(a, b, c) 的 length 是 3。每次传参后,内部累计非占位符参数数量,一旦达到 3 就立刻执行加法;不够就继续返回新函数。
- 不需要写
sum(1)(2)(3)()或sum()()这类额外调用 - 支持一次传多个:
sum(1, 2)(3)、sum(1)(2, 3)、sum(1, 2, 3)全部直接得 6 - 避免手动维护参数数组或判断“是否结束”,逻辑由 arity(形参长度) 驱动
支持占位符实现参数自由组合
真实场景中,参数顺序常不确定。例如你想先固定首尾两个数,中间一个稍后填:sum(1, _, 5)(3) → 9。这靠占位符实现:
- 定义一个唯一标识符,如
const _ = Symbol('placeholder') - 合并参数时跳过占位符位置,只统计已填值
- 只要非占位符参数数量 ≥ 原函数 length,就执行求和(未填位置不影响判断)
保持链式调用与函数身份一致
柯里化后的求和函数本身仍是函数,能继续接收参数,也能被当普通函数用:
立即学习“Java免费学习笔记(深入)”;
- 可赋值:
const add10 = sum(10),之后add10(5)→ 15 - 可嵌套:
sum(1)(2)(3)(4)累计到第 4 次才触发(若原函数是四参数) - 返回的每个中间函数都具备相同行为,无需额外封装或转换
一个可运行的精简实现
以下代码满足动态求和所有关键需求:
const _ = Symbol('curry placeholder');
function sum(...args) {
const fn = (...nums) => nums.reduce((a, b) => a + b, 0);
fn.length = 3; // 显式设为三参数,便于 curry 判断
return curry(fn)(...args);
}
function curry(fn) {
const arity = fn.length;
function curried(saved = []) {
return function(...newArgs) {
const merged = [];
let filledCount = 0;
for (let i = 0; i < Math.max(saved.length, arity); i++) {
const s = saved[i];
const n = newArgs[i];
if (n === _ || s === _) {
merged[i] = saved[i] ?? n;
} else {
merged[i] = n !== undefined ? n : s;
filledCount++;
}
}
if (filledCount >= arity) {
return fn(...merged.filter(x => x !== _));
}
return curried(merged);
};
}
return curried();
}
这样就能自然支持:sum(1, _, 5)(3)、sum(2)(4, 1)(2)、sum(1, 2, 3) ——全部按需求值,不绕弯。


















