函数科里化

554 阅读1分钟

前提知识

        //科里函数的基本知识
        function cc(...args) {
            console.log(args);//真数组[1,2,3]
            console.log(...args);//1 2 3 
        }
        //这时候可以不带入参数
        function ccc(){
            console.log(arguments);//类数组
        }

原理

其实就是接受参数,但不执行,等到所有参数都接到完之后再执行函数。

科里化函数(参数个数确定)

                //箭头函数,reduce函数,扩展运算符的参数表示
        //要求:函数返回的结果是参数的相加和
        function add(a,b,c,d){
            return [...arguments].reduce((a,b)=>a+b)
        }
        //封装科里函数
        function curry(fn){
            //获取到传入函数的参数个数
            let len=fn.length
            //通过闭包引用这个arg
            let arg=[]
            return function _c(){
                //将原来的参数和这次函数_c的参数进行整合
                arg=[...arg,...arguments]
                //说明参数还没有传完
                //后面还有参数,因此要返回函数_c
                //继续添加后面括号中的参数
                if(arg.length<len){
                    return _c
                }else{
                    //说明参数都在arg里面了就可以执行add函数了
                    //其实也可以fn(...arg)或者fn.apply(null,arg)
                    //下面的写法更加优雅,注意要把这个函数执行的结果返回出来,不让拿不到结果
                    return fn.apply(this,arg)
                }
            }
        }

        let a=curry(add)
        console.log(a(1)(2,3)(4));//10

参数不确定

        //参数不定
        function add1() {
            return [...arguments].reduce((a, b) => a + b)
        }
        function curry1(fn) {
            //不需要知道函数的长度了
            let arg = []
            return function _c() {
                arg = [...arg, ...arguments]
                //如果传入参数长度为0,没有参数了
                //那么久执行函数
                //注意此时后面必须跟一个(),代表结束传参
                if (arguments.length) {
                    return _c
                } else {
                    return fn.apply(this, arg)
                }
            }
        }
        let b = curry1(add1)
        //注意调用方式的不同
        console.log(b(1)(2)(3)());

引用

www.imooc.com/article/302…