js curry实现
柯里化(Currying)的概念
柯里化是一种将多参数函数转换为一系列单参数函数的技术。例如,f(a, b, c) 转换为 f(a)(b)(c)。
实现基础柯里化
以下是一个简单的柯里化实现,支持固定参数长度的函数:
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
支持占位符的柯里化
通过占位符(如 _)可以灵活跳过参数顺序:
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.shift() : arg);
return curried.apply(this, mergedArgs.concat(nextArgs));
};
}
};
}
使用示例:
const curriedSumWithPlaceholder = curryWithPlaceholder(sum);
console.log(curriedSumWithPlaceholder('_', 2)(1)(3)); // 6
无限参数柯里化
对于参数不固定的函数(如 ...args),需手动指定终止条件(如空参数调用):
function infiniteCurry(fn) {
return function curried(...args) {
if (args.length === 0) {
return fn.apply(this, args);
} else {
return function(...nextArgs) {
if (nextArgs.length === 0) {
return fn.apply(this, args);
}
return curried.apply(this, args.concat(nextArgs));
};
}
};
}
使用示例:
const add = infiniteCurry((...nums) => nums.reduce((a, b) => a + b, 0));
console.log(add(1)(2)(3)()); // 6
注意事项
- 参数长度检测:基础柯里化依赖
fn.length,因此不适用于可变参数函数(如...args)。 - 上下文绑定:使用
apply确保函数调用时的this正确。 - 性能:柯里化可能增加调用栈深度,需权衡可读性与性能。







