函数的柯里化createCurry:高阶函数(接收函数作为参数的函数),他接收函数A作为参数,运行后返回一个新的函数,且这个新的函数能够处理A的剩余参数。例:function A(a, b, c) {
}
var _A = createCurry(A);
_A(1, 2, 3);
_A(1, 2)(3);
_A(1)(2, 3);
_A(1)(2)(3);
A(1, 2, 3);
_A作为createCurry运行的返回值,他能处理A的剩余参数,所以上面运行结果都是等价的,所以柯里化也称为部分求值。原理:function add(a, b, c) {
return a + b + c;
}
===add和_add是等价的=====
function _add(a) {
return function(b) {
return function(c) {
return a + b + c;
}
}
}
add(1, 2, 3);
_add(1)(2)(3);
可以看出,柯里化函数运行过程其实是参数收集过程,每一次传入的参数收集起来,并在最里层处理
function createCurry(func, args) {
var arity = func.length;
var args = args || [];
return function() {
var _args = [].slice.call(arguments);
[].push.apply(_args, args);
if (_args.length < arity) {
return createCurry.call(this, func, _args);
}
return func.apply(this, _args);
}
}
例如:验证一串数字是否是正确的手机号function checkPhone(phoneNumber) {
return /^1[34578]\d{9}$/.test(phoneNumber);
}
而如果想要验证是否是邮箱呢function checkEmail(email) {
return /^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/.test(email);
}
我们还可能会遇到验证身份证号,验证密码等各种验证信息,因此在实践中,为了统一逻辑,我们就会封装一个更为通用的函数,将用于验证的正则与将要被验证的字符串作为参数传入function check(targetString, reg) {
return reg.test(targetString);
}
但是这样封装之后,在使用时又会稍微麻烦一点,因为会总是输入一串正则,这样就导致了使用时的效率低下。check(/^1[34578]\d{9}$/, '14900000088');
check(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'test@163.com');
这时,借助柯里化,在check的基础上再做一层封装,以简化使用:var _check = createCurry(check);
var checkPhone = _check(/^1[34578]\d{9}$/);
var checkEmail = _check(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/);
使用时变得更加直观与简洁:checkPhone('183888888');
checkEmail('xxxxx@test.com');
所以柯里化能应对更加复杂的逻辑封装,很灵活