函数柯里化及经典案例

函数柯里化及经典案例

先解释什么是柯里化,currying,把接收多个参数的函数变为接收单一单一参数的函数,并且返回接收剩余参数而且返回结果的新函数。

前因

我接收到柯里化是因为一次面试,题干是这样的

let a=add(1)(1)(3)() 

要求实现这个函数让里面的参数能到递加得到结果

const add=(a)=>{
     let current=a;
    let adder=function(b:any){
        if(b){
            current=current+b;
            return adder;
        }
        return current;
    }
    return adder;
}

这其实就是函数柯里化,有利用闭包,保持了current变量的在一段时间内的驻留内存,从而达到函数连续调用并计算出最后的结果值。

// 每个参数可传递多个参数。
function curry(...arg:any[]){
    let args=arg;
   let adder=  function(...arg:any[]){
             args.push(...arg);
          return adder; 
    }
    adder.toString = function () {
        return args.reduce(function (a:number, b:number) {
            return a + b;
        });
    }
    return adder;
}
lodash-curry柯里化函数

lodash-curry柯里化的核心代码。我认为没有问题。

function createCurry(func, bitmask, arity) {
      var Ctor = createCtor(func);

      function wrapper() {
        var length = arguments.length,
            args = Array(length),// args 持久保留的数据
            index = length,
            placeholder = getHolder(wrapper);

        while (index--) {
          args[index] = arguments[index];
        }
        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
          ? []
          : replaceHolders(args, placeholder);

        length -= holders.length;
          // 看剩下的参数
			// arity 参数的数量,
          // 用于确定需要继续递几次
        if (length < arity) {
          return createRecurry(
            func, bitmask, createHybrid, wrapper.placeholder, undefined,
            args, holders, undefined, undefined, arity - length);
        }
        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
          // 执行最后得到的结果,用于返回
        return apply(fn, this, args);
      }
    // 
      return wrapper;
    }

从lodash的实现来看,柯里化主要运用了闭包,用来保持我们的参数数据,然后用递归来接收接下来的函数调用。最后返回。

可应用场景
减少重复传递不变的部分参数
function simpleURL(protocol, domain, path) {
    return protocol + "://" + domain + "/" + path;
}
let myURL1 = _.curry(simpleURL)('https', 'mysite');
let res1 = myURL1('home.html');    //

console.log(res1);//https://mysite/home.html

let myURL2 = _.curry(simpleURL)('http', 'mysite');
let res2 = myURL2('aboutme.html');    //

console.log(res2);//http://mysite/aboutme.html
柯里化的callback传递给map,filter等函数
var getProp = _.curry(function (key, obj) {
    return obj[key]
});
var names = persons.map(getProp('name'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值