介绍
柯里化其实是函数式编程的一个过程,在这个过程中我们能把一个带有多个参数的函数转换成一系列的嵌套函数。它返回一个新函数,这个新函数期望传入下一个参数。简单的说就是把一个你写好的具有多个参数的函数可以一级级(递归+闭包)调用(每次传入一个参数)。
应用场景
我们希望用一个通用的正则模板实现项目中各种类型检查,包括但不限于手机号,邮件地址...
{
//定义主要柯里化主要逻辑处理
const curry = fn => {
const _c = (restNum, argsList) => restNum === 0 ? fn(...argsList) : x => _c(restNum - 1, [...argsList, x]);
return _c(fn.length, []);
}
//定义正则验证函数 regExp =>规则 value=>待检验对象
const MyReg = (regExp, value)=>console.log(regExp.test(value));
MyReg(/^1\d{10}$/, '18642838455') // 校验电话号码 true
const _check = curry(MyReg) //进行柯里化
const checkPhone = _check(/^1\d{10}$/) //生成工具函数,验证电话号码
checkPhone('18642838455') // 这样就实现了函数柯里化 true
}
关键部分是
const curry = fn => {
const _c = (restNum, argsList) => restNum === 0 ? fn(...argsList) : x => _c(restNum - 1, [...argsList, x]);
return _c(fn.length, []);
}
理解
- 首先
curry
函数接收一个函数,这个函数是我们真正的处理逻辑的函数 - 然后通过闭包,声明一个函数
_c
,_c
接收两个参数,一个是真正函数的参数列表长度的计数器,一个是传入参数的列表 - 在
_c
函数中判断真正函数的参数列表是否等于0,等于0代表参数已经全部都传入进来了,可以调用真正的函数去进行计算,并返回fn
函数进行计算然后返回结果;如果参数列表不等于0,则把参数列表的计数器-1,并把传入参数进行合并,然后使用返回_c
函数供尾递归调用。
上面就是柯里化的大体思路,主要实现是依赖闭包
和尾递归
来实现的,所以在性能上有优化的同时也是有一定的损失,对于性能要求很苛刻的程序可能需要酌情考虑,一般情况下合理使用柯里化是可以把代码的可读性提高很多。
老公我爱你