柯里化与反柯里化

柯里化与反柯里化

柯里化是指 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数。

核心思想是把多参数传入的函数拆成单参数(或部分)函数,内部再返回调用下一个单参数(或部分)函数,依次处理剩余的参数。

例如


// 传统写法
add(1,2,3)
// 柯里化写法
add(1)(2)(3)

柯里化本质上是降低通用性,提高适用性。比如当我们需要校验手机号


function checkMobile(regExp,mobile) {
    return regExp.test(mobile);  
}


checkMobile(/^1\d{10}$/, '186****1111'); // 校验电话号码

当需要校验多个手机号,传统写法如下

checkMobile(/^1\d{10}$/, '186****1111'); // 校验电话号码
checkMobile(/^1\d{10}$/, '186****2222'); // 校验电话号码
checkMobile(/^1\d{10}$/, '186****3333'); // 校验电话号码

乍一看也没什么毛病,但是通过柯里化,我们可以更加优雅的对函数进行封装

//函数柯里化
let _check = curry(checkMobile);
//生成工具函数
let checkCellPhone = _check(/^1\d{10}$/);

// 使用

checkCellPhone('186****1111'); // 校验电话号码
checkCellPhone('186****2222'); // 校验电话号码
checkCellPhone('186****3333'); // 校验电话号码

柯里化工具函数

简易实现


// 实现一个add方法,对 [1,2,3] 该数组求和
function sum(x) {
  return function (y) {
    return function (z) {
      return x + y + z
    }
  }
}
// 调用
sum(1)(2)(3) // 6

// 封装一个简易柯里化工具,实现对普通函数的柯里化
function curry(fn) {
 return function (x){
  return function (y) {
    return function (z) {
      return fn(x, y, z);
    };
   };
 }
}
var sum3 = curry(function (x, y, z) {
  return x + y + z;
});
console.log(sum3(1)(2)(3)); // 6

如果参数不固定这种封装方法就不够灵活

实现思路


TODO 通过函数的 length 属性,获取函数的形参个数,形参的个数就是所需的参数个数

具体封装


/**
 * 函数柯里化
 * @param fn    待柯里化的原函数
 * @param len   所需的参数个数,默认为原函数的形参个数
 */

function curry(fn,len = fn.length) {
    return _curry.call(this,fn,len) // 需要更改this的指向 到【待柯里化的原函数中】
}
/**
 * @param fn    待柯里化的原函数
 * @param len   所需的参数个数
 * @param args  已接收的参数列表
 */
function _curry(fn,len,...args) {
    return function (...params) {
        let _args = [...args,...params];
        if(_args.length >= len){
            return fn.apply(this,_args); // 执行原函数
        }else{
            return _curry.call(this,fn,len,..._args) // 参数累加
        }
    }
}

使用

let _fn = curry(function(a,b,c,d,e){
    console.log(a,b,c,d,e)
});


_fn(1)(2)(3)(4)(5)     // 输出: 1,2,3,4,5

反柯里化

与柯里化相对应。

  • 反柯里化则是扩大适用范围,创建一个应用范围更广的函数。
  • 柯里化是为了缩小适用范围,创建一个针对性更强的函数;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值