函数的柯里化

看了不少大佬的文章,终于对柯里化有了初步的理解,简单总结一下。
什么是柯里化?
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
看了概念还是一头雾水,用代码解释一下。
例如有一个简单的加法运算:

function add(a,b,c){
    return a+b+c
}
add(1,2,3);   //这是接受多个参数的函数

现在把它变换成接受单一参数的柯里化函数

function add(a){
  return function(b){
    return function(c){
       return a+b+c
    }
  }
}
add(1)(2)(3);   //接受单一参数

柯里化函数结合了闭包的用法,不了解闭包的先学习闭包噢
柯里化把简单的问题复杂化了,同时把复杂的问题自由化了,来看这么一个例子:

// 实现一个add方法,使计算结果能够满足如下预期:
 function add() {
	  let args = [...arguments];
	  function _add() {
	    args = args.concat([...arguments]);
	    return _add;
	  }
	  _add.toString = function() {
	    return args.reduce((pre, cur) => {
	      return pre + cur;
	    })
	  }
	  return _add;
	}
     add(1)(2)(3);    //f 6
     add(1, 2, 3)(4);   //f 10
     add(1)(2)(3)(4,5) ;  //f 15
     add(1)(2)(3).toString();   //6

函数有些难理解,建议debugger在浏览器看运行步骤。

柯里化的应用场景
手机号、邮箱的验证,我们一般会写一个通用的函数,将用于验证的正则和将要被验证的字符串作为参数传入。

function check(reg,targetString){
    return reg.test(targetString);
}

这样使用会有点冗余,每次都要重复写正则表达式

check(/^1[34578]\d{9}$/, '14900000088');
check(/^1[34578]\d{9}$/, '13714357188');
check(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'test@163.com');
check(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, '123478@163.com');

柯里化函数的运行过程其实是一个参数的收集过程,我们将每一次传入的参数收集起来,并在最里层处理,所以可以借助这个思路来封装一下。

function createCurry(func, args) {
    var arity = func.length;    //2      check函数形参的长度
    var args = args || [];
    return function() {
        var newArgs = [].slice.call(arguments);
        [].push.apply(newArgs, args);   //args参数push进newArgs
       // 如果参数个数小于最初的func.length,则递归调用,继续收集参数
        if (newArgs .length < arity) {
            return createCurry.call(this, func, newArgs);
        }
        // 参数收集完毕,则执行func
        return func.apply(this, newArgs );
    }
}
var checkPhone = createCurry(check)(/^1[34578]\d{9}$/);
var checkEmail =  createCurry(check)(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/);

最后调用就会更加简洁了。

checkPhone('14900000088');
checkPhone('13714357188');
checkEmail('xxxxx@test.com');

参考资料:https://www.jianshu.com/p/5e1899fe7d6b

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值