假设存在一个函数func
func
接受三个参数 a
b
c
那么函数最多被柯里化三次
function func(a, b, c) {
return a + b + c;
}
var c1 = curry(func, 1);
var c2 = curry(func, 2);
var c3 = curry(func, 3);
c3(); //6
参数定长的柯里化
function curry(fn) {
const argLen = fn.length;
const presetArg = [].slice.call(arguments, 1);
return function () {
const restArgs = [].slice.call(arguments);
const allArgs = [...presetArg, ...restArgs];
if (allArgs.length >= argLen.length) {
return fn.apply(this, allArgs);
} else return curry.call(null, fn, ...allArgs);
};
}
这样写我们的柯里化就支持三个参数的运算
function func(a, b, c) {
return a + b + c;
}
var currried = curry(func);
curried(1, 2, 3);
curried(1)(2, 3);
参数不定长的柯里化
我们需要让这个函数满足返回一个函数并且可以通过这个函数来得到我们要的值
function curry_unlimited(fn) {
const presetArg = [].slice.call(arguments, 1);
function curry_unlimited() {
const restArgs = [].slice.call(arguments);
const allArgs = [...presetArg, ...restArgs];
return curry_unlimited.call(null, fn, ...allArgs);
}
curry_unlimited.toString = function () {
return fn.apply(null, presetArg);
};
return curry_unlimited;
}
测试这个参数不定长的柯里化
const curriedSum = curry_unlimited(sum);
function sum(...args) {
return args.reduce((acc, curr) => acc + curr, 0);
}
// 测试不同的调用方式
console.log(curriedSum(1)(2)(3) + ""); // 输出 6
console.log(curriedSum(1, 2, 3)(4)(5) + ""); // 输出 15