什么是函数柯里化
函数柯里化就是给函数分步传参,每次传递部分参数,并返回一个接受剩余参数的函数,若有多个剩余参数,会多次递归,直至返回结果。
函数柯里化的实现
这样讲可能还不是很清楚,先来看一个题目,写一个currying函数使得fn不管以下面四种哪个方法返回的都是2。
function sum(a, b, c, d) {
console.log(a + b + c - d);
}
const fn = currying(sum)
fn(1, 2, 3)(4); // 2,这里只有一个剩余参数为4,会递归一次
fn(1, 2)(3)(4); // 2,这里一个剩余参数为3,另一个为4,递归两次
fn(1)(2, 3, 4); // 2,这里只有一个剩余参数为(2,3,4),递归一次
fn(1)(2)(3)(4); // 2,这里有三个剩余参数,分别为2,3,4,递归3次
function currying(fn1, args) { //args为上一次的参数
return function() {
let _args = [].slice.call(arguments); //此次的参数,即返回函数中的参数
// 首次调用时,若未提供上一次的参数args,则不用进行拼接
if (args !== undefined) {
_args = args.concat(_args);//注意是上一次参数后面拼接此次的参数,不要写反
}
// 递归调用
if (_args.length < fn1.length) {
return currying(fn1, _args);
}
// 递归出口
return fn1.apply(null, _args);
}
}
上述的curring就是函数柯里化的实现,以fn(1, 2, 3)(4)为例,分析上面这段代码:
fn1为题目中的sum函数,fn1.length=4
第一次args为undefined,_args为[1,2,3],长度小于4,继续递归
第二次args为上一次的_args[1,2,3],_args为[4],合并参数后的_args为[1,2,3,4],长度等于4,故返回fn1(1,2,3,4)的结果,即sum(1,2,3,4)