函数编程柯里化的一些知识点

145 阅读3分钟

1. 函数柯里化:

是一种将多参数函数转换为单参数函数的编程技术,他通过将一个多参数的函数转换为一系列使用部分应用技术的单参数函数,每个单参数函数返回另一个函数,直到所有参数被提供,最终执行原始函数。 特点:简化代码,提高维护性,功能单一化。 优点:功能内聚,降低耦合,降低代码的重复性。

高阶函数

        function somefn(a,b,fn){
            return fn(a)+fn(b);
        }
        function square(x){
            return Math.pow(x,2)
        }
        console.log(somefn(2,3,square))
        //打印出13

在日常开发当中会有有一些公用的功能可以单独封装出来,然后作为参数传入另一个函数作为参数。为高阶函数。这样的话 map数据处理函数,filter过滤函数,reduce归纳函数,find,findIndex,sort,replace 等等这些常用的函数都为高阶函数。 优点:便于函数扩展,例子 jquery封装的$ajax(url,data,fn);

柯里化函数

    function add(a=0,b=0,c=0,d=0){
        return a+b+c+d
     }
       function someFn(fn){
          let arg=[].slice.call(arguments,1);
          console.log(arg);//[1,2,3]
          return function(){
            //这里的this 指向current
            console.log(arguments);// 打印 [0:4]
            let newArg=arg.concat(Array.from(arguments))
            console.log(newArg);// 打印 [1, 2, 3, 4]
            //执行传下来的add
            return fn.apply(this,newArg)
          }
        }
     const current=someFn(add,1,2,3); 
     console.log(current(4));
     
     存在的问题在于,每次执行都要重新柯里化一次: **我称之为每次都要喊 咋瓦鲁多一次,麻烦。**
     const current1=someFn(add,1);
     const current2=current1(2); 打印出来3
     const current3=current2(3);打印出来6
     const current4=current3(4);..... 打印出来10

327907ed66fff29ea4519512967d56bd98230c29.jpg

递归执行 :喜提替身新技能:套娃滚雪球 “jojo”

    function rollingSnowballs(fn,len){
            var len=len||fn.length;
            let func= function someFn(fn){
            let arg=[].slice.call(arguments,1);
            return function(){
                let newArg=arg.concat(Array.from(arguments))
                return fn.apply(this,newArg)
            }
            }
        //  const current2=current1(add,2);
        //  const current3=current2(3);
        //  const current4=current3(4);
        //  这样就便于理解为啥要每次return 出来的都是一个新函数。相当于是current2,current3 这些。
            return function(){
                //这里的arguments 相当于每次你新创建出来的函数执行(1)(2)(3)
                let rollArg=arguments.length;
                // 判断每次传进来的参数是否传完 而且拿到的都是新值
                if(rollArg<len){
                 // 这里有个疑问 每次拿到rollArg=arguments.length 那岂不是每次都拿到最新的这里对                       
                 比就没意义了。所以要滚雪球
                 let rollingData=[fn].concat(Array.from(arguments))
                  // 这里得出的是[fn,2,....];
                  return rollingSnowballs(func.apply(this,rollingData),len-rollArg)  
                  // 这个很好理解相当于把每次声明current2,current3....用一个函数 重复执行rollingSnowballs   代替。                   
                  //len-rollArg 相当于每次都传最新的参数length去做对比,如果len的length  
                  //不变就无限了没有结果。 infinite 你承受不住 大脑 崩塌,无法想象 有无限这东西。 
                  // func.apply(this,formatedArr) 相当于 这个current1(add,2);
                }else{
                    //这里的相当于收集好了参数之后就统一输出。
                    return fn.apply(this,arguments)
                }
            }
        }
      
     const current=rollingSnowballs(add);
       
     console.log(current(1)(2)(3)(4));
     打印得出来10

来一口无限烟,一次吸五根。 630b79a05134e3412c7fc4b48532a3e8f90d87f4.jpg

欧拉!欧拉!欧拉

拓展应用在真实项目中的情况

6ea70f87b90057e7869f47c42049d5a2cb40c71a.jpg

一看手机:

IMG_202410214480_281x330.png

to be continue.........

来真的 一次吸五根烟,吃饭不给钱。 下载.jpg