什么是函数柯里化 currying?
做题时看到 currying
这个词还挺有意思的,本意是咖喱,翻译为中文叫柯里化,是因为是以逻辑学家 Haskell Curry 命名的。
arity(参数个数)是函数所需的形参的数量。
函数柯里化(Currying)意思是把接受多个 arity 的函数变换成接受单一 arity 的函数。
换句话说,就是重构函数让它接收一个参数,然后返回接收下一个参数的函数,依此类推。
这有点像套娃,就是把含有多个参数的函数,分解为一个一个的函数进行返回。
例一:
function unCurried(x, y) {
return x + y;
}
function curried(x) {
return function(y) {
return x + y;
}
}
// ES6 写法
const curried = x => y => x + y
curried(1)(2) // 3
例二:
function add(x) {
return function(y) {
return function(z) {
return x + y + z
}
}
}
add(10)(20)(30); // 60
柯里化的作用之一:参数复用(正则匹配案例)
函数柯里化具体怎样使用呢?我搜到了这篇文章函数柯里化 ,现在把其中一个正则表达式的例子抽出来。
使用通用函数(平常写的代码)
function checkByRegExp(regExp, str) {
return regExp.test(str)
}
// 校验手机号
checkByRegExp(/^1\d{10}$/, '15152525634');
checkByRegExp(/^1\d{10}$/, '13456574566');
checkByRegExp(/^1\d{10}$/, '18123787385');
// 校验邮箱
checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'fsds@163.com');
checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'fdsf@qq.com');
checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'fjks@qq.com');
它的缺点是:
- 校验同一类型的数据时,相同的正则写了很多次
- 代码可读性较差,如果没有注释,我们并不能一下就看出来正则的作用
函数柯里化
// 第一步:定义柯里化函数
function curryingCheckByRegExp(regExp) {
return function(str) {
// console.log(regExp.test(str)) // 6 个 true
return regExp.test(str)
}
}
// 第二步:将最外层函数保存为变量
// 校验手机
const checkPhone = curryingCheckByRegExp(/^1\d{10}$/)
// 校验邮箱
const checkEmail = curryingCheckByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/)
// 第三步:调用第二层函数
// 校验手机号
checkPhone('15152525634');
checkPhone('13456574566');
checkPhone('18123787385');
// 校验邮箱
checkEmail('fsds@163.com');
checkEmail('fdsf@qq.com');
checkEmail('fjks@qq.com');
柯里化的其他作用,请看这篇文章:前端面试手写代码——函数柯里化