在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
简单的来说柯里化就是把原本多参数的函数,转换成每次只接受一个参数,但是参数可传递的函数链来使用。
简单的例子
// 柯里化前
let plus = (a,b) => a + b
plus(1,2) // 输出:3
// 柯里化后
let plusTwoNum = (a,b)=> a+b
let plus = fpu.curry(plusTwoNum)
plus(1)(2) // 输出:3
上面是代码是很简单的一个函数柯里化例子,乍一看是没有什么特别的用处的,但是在某些场景是可以发乎很大的用处的,比如说当程序需要运行上面的sum函数,但是参数确实分开获取的,在某一时刻只能获取到其中的一个值a,值b需要一定条件后才能拿到的时候就可以使用柯里化来完美的解决这个问题。
下面简单说一下柯里化的简单实现(想要支持更复杂的特性,需要自己进行增强)
先上代码
// 函数自动柯里化
// eg: new FPUtiles().curry((a,b,c,d) => a+b+c+d)(1)(2)(3)(4)
curry(fn){
const _fn = (restNum,argList) => restNum === 0 ? fn(...argList) : x => _fn(restNum-1,[...argList,x])
return _fn(fn.length,[])
}
下面开始整理思路:
- 首先curry函数接收一个函数,这个函数是我们真正的处理逻辑的函数
- 然后通过闭包,声明一个函数
_fn
,_fn
接收两个参数,一个是真正函数的参数列表长度的计数器,一个是传入参数的列表 - 在
_fn
函数中判断真正函数的参数列表是否等于0,等于0代表参数已经全部都传入进来了,可以调用真正的函数去进行计算,并返回fn
函数进行计算然后返回结果;如果参数列表不等于0,则把参数列表的计数器-1,并把传入参数进行合并,然后使用返回_fn
函数供尾递归调用。
上面就是柯里化的大体思路,主要实现是依赖闭包
和尾递归
来实现的,所以在性能上有优化的同时也是有一定的损失,对于性能要求很苛刻的程序可能需要酌情考虑,一般情况下合理使用柯里化是可以把代码的可读性提高很多。