函数柯里化

370 阅读2分钟

先说下柯里化的概念
在计算机科学中,柯里化(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);

增加闭包,这样每次执行可以刷新保存参数的容器