javascript实现函数柯里化与反柯里化过程解析

  

函数柯里化(黑人问号脸)? ? ?鞭笞(黑人问号脸)? ? ?妥妥的中式翻译既视感;下面来一起看看究竟什么是函数柯里化:

  

维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第一个参数)的函数,并返回接受剩余的参数而且返回结果的新函数的技术。其由数学家布鲁克斯Haskell Curry提出,并以咖喱命名。

  

概念往往都是干涩且难懂的,让我们用人话来解释就是:如果我们不确定这个函数有多少个参数,我们可以先给它传入一个参数,然后通过JS闭包(如若不懂JS闭包,请先学习闭包知识点再来学习本篇博文https://www.jb51.net/article/171398.htm)来进行返回一个函数,内部函数接收除开第一个参数外的其余参数进行操作并输出,这个就是函数的柯里化;

  

举个小例子:

  

场景(需求):

  

众所周知程序员每天加班的时间还是比较多的,如果我们需要计算一个程序员每天的加班时间,那么我们的第一反应应该是这样;

        var加班=0;   函数的时间(x) {   返回加班+=x;   }      (1);//1   (2);//3   (3);//6      

上面的代码固然没有问题,可是需要每天调用都算加一下当天的时间,很麻烦,并且每调用一次函数都要进行一定的操作,如果数据量巨大,有可能会有影响性能的风险,那么有没有可以偷懒又能解决问题的办法呢?有的!

        函数的时间(x) {   返回函数(y) {   返回x + y;   }   }      var=时间(0);   (3);      

但是上面代码依然存在问题,在实际开发中很多时候我们的参数是不确定的,上面代码虽然简单的实现了柯里化的基本操作,但是对于参数不确定的情况是处理不了的,所以存在着函数参数的局限性,不过我们从上面的代码中基本可以知道函数柯里化是个啥意思了;就是一个函数调用的时候只允许传入一个参数,然后通过闭包返回内部函数去处理和接收剩余参数,返回的函数通过闭包的方式记住了时间的第一个参数;

  

我们再来把代码改造一下:

     //首先定义一个变量接收函数   var=加班(函数(){//定义一个数组用来接收参数   var args=[];//这里运用闭包,调用外部函数返回一个内部函数   返回函数(){//参数是浏览器内置对象,专门用来接收参数//如果参数的长度为0即没有参数的时候   如果参数。长度===0){//定义变量用来累加   var=0;//循环累加,用我和参数的长度进行比较   (var=0, l=args.length;我& lt;l;我+ +){//进行累加操作等价于时间=时间+ args(我)   时间+=args(我);   }//返回累加的结果   返回时间;//如果参数对象参数长度不为零,即有参数的时候   其他}{//定义的空数组添加参数参数作为数组项,第一个参数古args作为改这个指变向,第二个参数参数把剩余参数作为数组形式添加至空数组中   [].push。应用(args参数);   }   }   })();      加班(3.5);//第一天   加班(4.5);//第二天   加班(2.1);//第三天//?      控制台。日志(加班());//10.1      

代码经过我们的改造已经实现了功能,但是这不是一个函数柯里化的完整实现,那么我们要怎么完整实现呢?下面我们来介绍一种通用的实现方式:

  

通用的实现方式:

     //定义方法局部套用,先传入一个参数   var鞭笞=函数(fn) {//定义空数组装参数对象的剩余参数   var args=[];//利用闭包返回一个函数处理剩余参数   返回函数(){//如果参数的参数长度为0,即没有剩余参数   如果(arguments.length===0) {//执行上面方法//这里的这个指向下面的年代,类似于(),代表参数长度为0的时候直接调用函数   返回fn.apply(这个,args)   }   console.log(参数)//如果参数的参数长度不为0,即还有剩余参数//在数组的原型对象上添加数组,应用用来更改这个的指向为参数//将[].slice.call(参数)的数组添加到原型数组上//这里的[].slice.call(参数)===Array.prototype.slice.call(参数)实质上就是将参数对象转成数组并具有片功能      Array.prototype.push.apply (args, [] .slice.call(参数)//args.push ([] .slice.call(参数)   console.log (args)//这里返回的arguments.callee是返回的闭包函数,被是参数对象里面的一个属性,用于返回正被执行的函数对象   返回arguments.callee   }   }//这里调用局部套用方法并传入添加函数,结果会返回闭包内部函数   var s=局部套用(添加);//调用闭包内部函数,当有参数的时候会将参数逐步添加到args数组中,待没有参数传入的时候直接调用//调用的时候支持链式操作   (1)(2)(3)();//也可以一次性传入多个参数   (1、2、3);   console.log (());

javascript实现函数柯里化与反柯里化过程解析