函数柯里化 js实现
函数柯里化的概念
柯里化(Currying)是一种将多参数函数转换为一系列单参数函数的技术。通过柯里化,可以将一个接受多个参数的函数拆分为多个嵌套的函数,每个函数只接受一个参数并返回一个新函数,直到所有参数被收集完毕并执行最终计算。
基本实现方法
以下是一个简单的柯里化函数实现示例,支持固定参数数量的函数:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
}
};
}
使用示例:
function sum(a, b, c) {
return a + b + c;
}
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 输出 6
支持占位符的柯里化
某些场景需要更灵活的柯里化,例如允许跳过某些参数(通过占位符暂存位置)。以下是一个支持占位符的实现:
const _ = Symbol('placeholder');
function curryWithPlaceholder(fn) {
return function curried(...args) {
const complete = args.length >= fn.length && !args.includes(_);
if (complete) {
return fn.apply(this, args);
} else {
return function(...nextArgs) {
const mergedArgs = args.map(arg => arg === _ && nextArgs.length ? nextArgs.shift() : arg);
return curried.apply(this, [...mergedArgs, ...nextArgs]);
};
}
};
}
使用示例:
function multiply(a, b, c) {
return a * b * c;
}
const curriedMultiply = curryWithPlaceholder(multiply);
console.log(curriedMultiply(_, 2)(1)(3)); // 输出 6(1 * 2 * 3)
无限参数的柯里化
对于参数数量不固定的函数(如add(1)(2)(3)...),需通过显式调用(如.value())触发计算:
function infiniteCurry(fn) {
let accumulatedArgs = [];
const wrapper = function(...args) {
accumulatedArgs.push(...args);
return wrapper;
};
wrapper.value = function() {
const result = accumulatedArgs.reduce(fn);
accumulatedArgs = [];
return result;
};
return wrapper;
}
使用示例:
const add = infiniteCurry((a, b) => a + b);
console.log(add(1)(2)(3).value()); // 输出 6
实际应用场景
- 参数复用:提前固定部分参数(如配置项),后续只需传递动态参数。
- 延迟执行:分步传递参数,直到满足条件才触发最终计算。
- 函数组合:与
compose结合,构建可读性更高的流水线操作。
注意事项
- 原函数的参数长度(
fn.length)需明确,否则需手动指定参数数量。 - 箭头函数无
arguments和length属性,可能影响柯里化行为。 - 性能敏感场景需谨慎使用,嵌套函数调用可能带来额外开销。







