高阶函数应用--currying

1,659 阅读3分钟

热身!

要实现三个几个数相加,我们一定会这样写:

function add(a,b,c){
           return a+b+c;
       }
    var total=add(1,2,3)

对啊,这样写没错。但是现在我要改需求了,要求--“结合闭包,函数只能有一个参数,并且完成以上能力”,这时候相信你已经想到了要用函数的柯里化来实现,牛逼!

在学习curring之前我们先来认识高阶函数

高阶函数?

高阶函数的特点:

  • 函数可以作为参数被传递;
  • 函数可以作为返回值输出。

显然,JavaScript语言中的函数就满足高阶函数的条件。在实际开发中也有很多应用,我们现在就讲讲其中的一个应用--curring!

函数柯里化

curring也称部分求值。为什么?来讲讲它的概念,你就明白了。

一个curring的函数首先会接受一些参数,接受了这些参数后,该函数并不是立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。等到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。其实简而言之就是:把一个接受N个参数的函数转变成一个接受一个单一参数的函数,并且返回接受余下参数的新函数。

扔了这么多干货,到解决任务的时候了

柯里化简单实现:

实现上面要求:

function curriedAdd(a){
        return function(b){
            return function(c){
                return a+b+c;
                console.log(a+b+c);
            }
        }
    }
// 函数嵌套函数自动构成了闭包
curriedAdd(1)(2)(3)

函数只接受一个参数,并且返回一个函数。函数嵌套函数自动构成了闭包,闭合空间的引用一直保留,前两次都没有求值,其变量一直保留到最后一次求值。

到这里大家肯定理解了function curring 了,那我们来个进阶!

question:

如果我们要编写一个计算每个月的开销的函数。自然,要记录下每天的开销再求和。

代码实现:

var currying=function(fn){
    var args=[];
    return function(){
        if(arguments.length===0){
            return fn.apply(this,args);
        }else{
            [].push.apply(args,arguments);
            return arguments.callee;
        }
    }
};
var cost=(function(){
    var money=0;
    return function(){
        for(var i=0,l=arguments.length;i<1;i++){
            money+=arguments[i];
        }
        return money;
    }
})();
var cost=currying(cost);//转化成curring函数
cost(100);//未真正求值
cost(200);//未真正求值
cost(300);//未真正求值

console.log(cost());//求值并输出:600

这就实现了柯里化的函数。当调用cost()时,如果明确地带上了一些参数,这里的cost(100),cost(200),cost(300),表示此时并不进行真正的求职计算,而是把这些参数保存起来,保存在[]中,此时cost函数返回另外一个函数arguments.callee。只有当我们以不带参数的形式执行cost()时,才利用前面保存的所有,真正开始执行求值计算。

如果你觉得收获了currying,感谢star 😄