curry js实现
以下是使用 JavaScript 实现柯里化(Curry)的几种方法:
基础柯里化实现
通过闭包和递归实现一个通用的柯里化函数:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
};
}
};
}
// 示例用法
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.slice(0, fn.length).includes(curryWithPlaceholder.placeholder);
if (complete) {
return fn.apply(this, args);
} else {
return function(...args2) {
const mergedArgs = args.map(arg =>
arg === curryWithPlaceholder.placeholder && args2.length ? args2.shift() : arg
).concat(args2);
return curried.apply(this, mergedArgs);
};
}
};
}
curryWithPlaceholder.placeholder = Symbol();
// 示例用法
const _ = curryWithPlaceholder.placeholder;
const curriedSum2 = curryWithPlaceholder(sum);
console.log(curriedSum2(1, _, 3)(2)); // 6
无限参数柯里化
实现一个不依赖函数参数长度的柯里化版本:
function infiniteCurry(fn) {
return function curried(...args) {
return function(...args2) {
const allArgs = [...args, ...args2];
if (args2.length === 0) {
return allArgs.reduce(fn);
}
return curried(...allArgs);
};
};
}
// 示例用法
const add = infiniteCurry((a, b) => a + b);
console.log(add(1)(2)(3)(4)()); // 10
自动柯里化装饰器
使用ES6 Proxy实现自动柯里化:

function autoCurry(fn) {
return new Proxy(fn, {
apply(target, thisArg, args) {
if (args.length >= target.length) {
return target.apply(thisArg, args);
}
return autoCurry(target.bind(thisArg, ...args));
}
});
}
// 示例用法
const curriedSum3 = autoCurry(sum);
console.log(curriedSum3(1, 2, 3)); // 6
console.log(curriedSum3(1)(2, 3)); // 6
每种实现方式适用于不同场景,基础柯里化适合固定参数函数,占位符版本提供更大灵活性,无限参数柯里化适合可变参数函数,Proxy实现则提供了更简洁的语法。






