热身!
要实现三个几个数相加,我们一定会这样写:
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()时,才利用前面保存的所有,真正开始执行求值计算。