什么是柯里化( curry)

在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。

举例来说,一个接收3个参数的普通函数,在进行柯里化后, 柯里化版本的函数接收一个参数并返回接收下一个参数的函数, 该函数返回一个接收第三个参数的函数。 最后一个函数在接收第三个参数后, 将之前接收到的三个参数应用于原普通函数中,并返回最终结果。

  1. // 数学和计算科学中的柯里化:
  2. //一个接收三个参数的普通函数
  3. function sum(a,b,c) {
  4. console.log(a+b+c)
  5. }
  6. //用于将普通函数转化为柯里化版本的工具函数
  7. function curry(fn) {
  8. //...内部实现省略,返回一个新函数
  9. }
  10. //获取一个柯里化后的函数
  11. let _sum = curry(sum);
  12. //返回一个接收第二个参数的函数
  13. let A = _sum(1);
  14. //返回一个接收第三个参数的函数
  15. let B = A(2);
  16. //接收到最后一个参数,将之前所有的参数应用到原函数中,并运行
  17. B(3) // print : 6

柯里化的用途

  1. function checkByRegExp(regExp,string) {
  2. return regExp.test(string);
  3. }
  4. checkByRegExp(/^1\d{10}$/, '18642838455'); // 校验电话号码
  5. checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'test@163.com'); // 校验邮箱

多次校验的情况就会很繁琐

  1. checkByRegExp(/^1\d{10}$/, '18642838455'); // 校验电话号码
  2. checkByRegExp(/^1\d{10}$/, '13109840560'); // 校验电话号码
  3. checkByRegExp(/^1\d{10}$/, '13204061212'); // 校验电话号码
  4. checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'test@163.com'); // 校验邮箱
  5. checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'test@qq.com'); // 校验邮箱
  6. checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, 'test@gmail.com'); // 校验邮箱

如果使用了柯里化函数

  1. //进行柯里化
  2. let _check = curry(checkByRegExp);
  3. //生成工具函数,验证电话号码
  4. let checkCellPhone = _check(/^1\d{10}$/);
  5. //生成工具函数,验证邮箱
  6. let checkEmail = _check(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/);
  7. checkCellPhone('18642838455'); // 校验电话号码
  8. checkCellPhone('13109840560'); // 校验电话号码
  9. checkCellPhone('13204061212'); // 校验电话号码
  10. checkEmail('test@163.com'); // 校验邮箱
  11. checkEmail('test@qq.com'); // 校验邮箱
  12. checkEmail('test@gmail.com'); // 校验邮箱

如何封装函数

  1. /**
  2. * 将函数柯里化
  3. * @param fn 待柯里化的原函数
  4. * @param len 所需的参数个数,默认为原函数的形参个数
  5. */
  6. function curry(fn,len = fn.length) {
  7. return _curry.call(this,fn,len)
  8. }
  9. /**
  10. * 中转函数
  11. * @param fn 待柯里化的原函数
  12. * @param len 所需的参数个数
  13. * @param args 已接收的参数列表
  14. */
  15. function _curry(fn,len,...args) {
  16. return function (...params) {
  17. let _args = [...args,...params];
  18. if(_args.length >= len){
  19. return fn.apply(this,_args);
  20. }else{
  21. return _curry.call(this,fn,len,..._args)
  22. }
  23. }
  24. }