函数柯里化

函数柯里化

  函数柯里化Currying指的是把函数与传递给它的参数相结合,产生出一个新的函数

  原理:Currying通过创建一个保存着原始函数(对象)和要被套用的参数的闭包来工作。它返回另一个函数,当函数被调用时,会返回调用原始函数(对象)的结果,并传递调用curry时的参数“加上”当前调用的参数。”加上”是通过Array.concat()方法连接两个参数数组。

  上面的原理balabala一大顿,我都没看懂,所以为了更容易懂,还是得看代码:

1
2
3
4
5
6
7
8
9
10
11
12
Function.prototype.method=function(name,func){
this.prototype[name]=func;
return this;
}
Function.method("curry",function(){
var slice=Array.prototype.slice,
args=slice.apply(arguments),
that=this;
return function(){
return that.apply(null,args.concat(slice.apply(arguments)));
};
});

  然后接下来我们就可以看到它运用的结果

1
2
3
4
5
function add(num1,num2){
return num1+num2;
}
var add1=add.curry(1);
alert(add1(6)); //7

  这里的method方法中,要注意四点:

1.arguments对象保存着函数被调用时的参数列表,它是一个类数组对象,有一个length属性但没有任何数组的方法。

  第一个arguments是curry()函数的参数,return里的arguments是return function()的参数,这样可能听不懂,其实在例子中就是add1()函数里的参数。

2.正因为第一点,所以要想在最后使用args.concat,必须将arguments对象转换为一个真的数组,这里用Array.prototype.slice()方法,它可以将一个类数组(Array-like)对象/集合转换成一个新数组。

  具体见:MDN文档

3.第一个that=this;中的this在这里属于方法调用模式,绑定到调用该方法的对象上,即一个Function对象。

  所以add.curry(1),this被绑定到add函数对象上

4.调用函数的方法apply(要绑定给this的值,参数数组)

  具体可见博客中“JS中的apply()使用详解一节”。

  最后我们再结合代码来看curry方法的具体作用:

1
2
3
4
5
6
7
8
9
10
Function.method("curry",function(){
//curry方法通过创建一个保存着原始函数和要被套用的参数的闭包来工作。
var slice=Array.prototype.slice,
args=slice.apply(arguments), //要被套用的参数
that=this; //that=this保存着原始函数对象
return function(){ //闭包 && 它返回另一个函数
return that.apply(null,args.concat(slice.apply(arguments)));
//当函数被调用时,会返回调用原始函数的结果,并传递调用curry时的参数“加上”当前调用的参数
};
});

  所以当执行add1(6)时,相当于执行了add.apply(null,args.concat(slice.apply(arguments))),即执行了add(curry中的参数1,自己的参数6),所以放回1+6=7.

#####  这样就好理解柯里化的概念了:把函数与传递给它的参数相结合,产生出一个新的函数。

  add函数使用curry(参数)方法=>add.curry(参数);把函数与传递给它的参数 相结合,
  产生一个新的函数add1=>var add1=add.curry(1);
  用处就是可以用add1函数给原函数add传参,现阶段光是理论懂了,但是不懂具体用在哪,后期一定会再补充。

文章目录
  1. 1. 函数柯里化
    1. 1.0.1. 1.arguments对象保存着函数被调用时的参数列表,它是一个类数组对象,有一个length属性但没有任何数组的方法。
    2. 1.0.2. 2.正因为第一点,所以要想在最后使用args.concat,必须将arguments对象转换为一个真的数组,这里用Array.prototype.slice()方法,它可以将一个类数组(Array-like)对象/集合转换成一个新数组。
    3. 1.0.3. 3.第一个that=this;中的this在这里属于方法调用模式,绑定到调用该方法的对象上,即一个Function对象。
    4. 1.0.4. 4.调用函数的方法apply(要绑定给this的值,参数数组)
,