先说下柯里化的概念
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。 --引自百度百科
逻辑方面可以这么理解
柯里化函数接受一个函数
如果这个函数形参只有一个或者没有,就可以直接返回这个函数,不需要柯里化
那么如果是多个的情况就要分条件处理了
如果参数没获取够之前就是一直保存参数的操作,如果参数存够了就执行原来那个函数,这里有三个关键点,
1.用一个容器将传入的参数存起来
2.每存一次判断参数有没有存够
3.根据参数有没有存够决定需要返回出去什么,继续存参数或者执行函数
然后我就写了以下这个第一版科里化函数
function curry(fn) {
if (fn.length <= 1) {
return fn;
}
let arr = [];
return function keep(...a) {
arr.push(...a);
if (arr.length >= fn.length) {
return fn(...arr);
} else {
return keep;
}
}
}
function add(a, b, c, d) {
return a + b + c + d;
}
const f = curry(add);
//测试一下
const s1 = f(1)(2)(3)(4);
console.log(s1);
const s2 = f(2, 3)(4, 5);//执行到这里会出问题,因为用于存参数的arr没有初始化清空
console.log(s2);
但是在第二次执行获取s2的时候,报错了因为用于保存参数的arr不会在每次重新执行的时候清空
再来一版
function curry(fn) {
if (fn.length <= 1) {
return fn;
}
return (function (...p) {
return function recur(...a) {
p.push(...a);
if (p.length >= fn.length) {
return fn(...p);
} else {
return recur;
}
}
});
}
function add(a, b, c, d) {
return a + b + c + d;
}
const f = curry(add);
const s1 = f(1)(2)(3)(4);
console.log(s1);
const s2 = f(2, 3)(4, 5);
console.log(s2);
增加闭包,这样每次执行可以刷新保存参数的容器