维基百科中的定义:bash
在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,而且返回接受余下的参数并且返回结果的新函数的技术。闭包
换句话说就是把一个有n个参数的函数转换成n个嵌套的函数,每一个函数只接受一个参数,并返回一个新函数。也就是把f(a,b,c)
转化为f(a)(b)(c)
。函数
例如一个函数接受a, b, c三个参数,返回它们的乘积:ui
function multiply(a, b, c) {
return a * b * c;
}
复制代码
运行此函数,咱们在参数中依次传入1,2,3,返回6。this
multiply(1,2,3); // 6
复制代码
让咱们看一下柯里化以后的样子:spa
function multiply(a) {
return (b) => {
return (c) => {
return a * b * c
}
}
}
multiply(1)(2)(3) // 6
复制代码
咱们把multiply(1,2,3)
变成了multiply(1)(2)(3)
的形式。经过把一个多参函数转换成一系列嵌套的函数,每一个函数依次接受一个参数,这就是函数柯里化。code
或者换一种写法能够更容易理解:ip
function multiply(a) {
return (b) => {
return (c) => {
return a * b * c
}
}
}
const mul1 = multiply(1);
const mul2 = mul1(2);
const result = mul2(3); // 6
复制代码
multiply函数接受一个a参数,咱们传入1。mult1
等于multiply(1)
就等于it
(b) => {
return (c) => {
return a * b * c
}
}
复制代码
而且接受一个参数b。以此类推,mul1(2)
传入2,而后赋值给mult2
等于io
(c) => {
return a * b * c
}
复制代码
最后mul2(3)
返回a * b * c
。因为闭包的特性会保存以前传入的值1和2,最后得出6。
假设咱们有一个函数用来计算三个物体的体积。
function volume(l, w, h) {
return l * w * h;
}
volume(200,30,100) // 2003000
volume(32,45,100); //144000
volume(2322,232,100) // 53870400
复制代码
从上面代码能够看出,若是每一个物体的高度都是100,咱们须要重复传三次。 若是使用柯里化函数能够避免:
function volume(h) {
return (w) => {
return (l) => {
return l * w * h
}
}
}
//固定高度
const itemHeight = volume(100);
//计算其余不一样状况
itemHeight(30)(200);
itemHeight(45)(32);
itemHeight(232)(2322);
复制代码
合成两个函数的简单代码以下:
var compose = function(f,g) {
return function(x) {
return f(g(x));
};
};
复制代码
f(x)
和g(x)
合成为f(g(x))
,有一个隐藏的前提,就是f和g都只能接受一个参数, 其中就运用了函数柯里化。
Partial Application(偏函数应用)很容易和函数柯里化混淆,它是指使用一个函数并将其应用一个或多个参数,但不是所有参数,在这个过程当中建立一个新函数,这个函数用于接受剩余的参数。这段话很不容易理解,具体看下面的例子:
function multiply(a,b,c){
return a * b * c;
}
//生产偏函数的工厂
function partial(fn,a){
return function(b,c){
return fn(a,b,c);
}
}
//变量parMulti接受返回的新函数
var parMulti = partial(multiply,1);
//在调用的时候传入剩余的参数
parMulti(2,3); // 6
复制代码
partial
函数能够帮咱们生成一个偏函数。partial
函数生成一个偏函数并赋值给parMulti
,其中预设一个值1
。parMulti
接受剩余参数2,3
结合前面预设的1
得出最终结果。
例如bind函数可让咱们传入一个或多个想要预设的参数,以后返回一个新函数,并拥有指定的this值和预设参数。当绑定函数被调用时,这些参数会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面。
function addition(x, y) {
return x + y;
}
const plus5 = addition.bind(null, 5)
plus5(10) // output -> 15
plus5(20) // output -> 25
复制代码
咱们预先传入了参数5
,并返回了一个新函数赋值给plus5
,此函数能够接受剩余的参数。调用plus5
传入剩余参数10
得出最终结果15
,如传入20
得出25
。偏函数经过设定预设值,帮咱们实现代码上的复用。
柯里化和偏函数都是用于将多个参数函数,转化为接受更少参数函数的方法。传入部分参数后,处于中间状态的函数能够做为固定值进行复用。可是其中不一样之处在于: