javascript中的函数柯里化
函数柯里化是将接受多个参数的函数转换成可以接受一个参数的函数,且转换后的函数能够处理剩余参数并返回执行结果。
以下代码是对一个求和函数进行柯里化处理后的效果:
// 接受多个参数的函数
function add (a, b, c) {
return a + b + c
}
// 经过柯里化处理后生成函数_add
var _add = curry(add)
// _add可以接受一个参数,且能够处理剩余参数并返回执行结果
_add(1)(2)(3) // 6
求和函数add原本可以接收三个参数进行求和,经过柯里化处理后生产一个_add函数,我们可以对_add函数逐个传参,最终输出求和结果
那么如何实现上面例子中的curry函数呢?
首先先对函数柯里化过程中做了些啥进行分析:1、柯里化处理的对象是函数,说明curry函数的参数得是个函数;2、经过柯里化处理的函数,它可以多次调用,说明curry函数内部会多次return一个函数;3、多次调用后会将所有的参数执行并返回最终结果
经过上面简单的分析,可以动手实现一下curry函数,代码如下:
function curry(fn, args){
// 定义一个args来收集已传入的参数
var args = args || []
return function (){
// 利用闭包来获取已收集的传参,并与新调用时传入的参数集合
var _args = args.concat([].slice.call(arguments))
// 根据传入的函数fn的参数长度来决定柯里化后的函数可调用的次数
if(_args.length < fn.length){
// 如果收集的参数个数小于fn的形参个数,则继续柯里化
return curry.call(this, fn, _args)
}
// 当收集的参数的个数等于fn的形参个数时,返回执行结果
return fn.apply(this, _args)
}
}
对上面的代码进行测试:
_add(1)(2)(3) // 6
_add(2)(3)(4) // 9
上述就是函数柯里化的简单实现
总结:
函数柯里化是将接受多个参数的函数转换成每次接受一个参数的函数,转换后的函数能够处理剩余参数并返回最终执行结果;
函数柯里化主要做了两个工作,分别是:1、收集参数;2、执行函数;
函数柯里化利用了闭包对多次调用的传参进行存储,并通过判断收集参数的个数与执行函数的形参个数是否相等,来决定函数是否继续柯里化,继续柯里化的时候采用了递归的方式;
在柯里化过程中可以看出,通过递归可以持续柯里化,最终会有一个临界条件来让柯里化停止,并执行函数返回结果,上面例子中的临界条件就是对比收集参数的个数与执行函数参数的个数;
最后,将收集的参数代入执行函数中返回最终结果;