柯里化函数的实现

什么是柯里化函数

引用百度百科中对柯里化的解释

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

用经典的加法器来举例

 function add(a, b) {
    return a + b;
  }
  add(1, 2); // 3

这是一个最简单的加法函数,作用是把传入的a,b两个参数相加并把相加后的结果返回。

下面我们用柯里化的思想对这个函数进行改写。

 function add(a) {
    return function (b) {
      return a + b;
    };
  }
  add(1)(2); // 3

柯里化的思想就是要求我们把需要接受两个参数的函数改写成了接受一个参数并返回一个函数来接受第二个参数。

上面只是一个简单的例子,如果我们要执行add(1)(2)(3)这样的函数呢?

实现一个通用的累加器

首先我们要实现柯里化函数就需要把之前的每个参数保存起来,上面的方法通过闭包实现了对参数的保存,下面我们需要的就是通过不断的接受参数返回函数处理剩下的参数即可。

  function add(...outer) {
    function innerAdd(...inner) {
      return add(...outer, ...inner);
    }
    return innerAdd;
  }

这里我们用递归的思想,创建一个innerAdd函数,这个函数用来接受剩下的参数,并返回add函数且将之前的参数与当前的参数合并起来执行。而add函数则返回innerAdd这个函数体。

举个例子

  console.log(add(1)(2)(3));
  // 1.add(1)
  // 2.innerAdd(2)
  // 3.add(1,2)
  // 4.inner(3)
  // 5.add(1,2,3)
  // 6.inner

第一步:我们执行了add(1)这个函数,返回结果是innerAdd
第二步:返回的innerAdd遇到了(2),所以立马执行innerAdd(2)这个函数
第三步:innerAdd(2)执行后返回了add(1,2),这里用扩展运算符把上一次和本次的参数合并
第四步:add(1,2)又返回了innerAdd
第五步:同第三步,此时返回了add(1,2,3)
第六步:add(1,2,3)执行完后返回innerAdd这个函数体

我们最终的目的是要将1,2,3累加起来,第六步中add的参数就是我们需要的所有值,但此时返回的是innerAdd函数体,所有打印的结果是这个函数而不是我们想要的6。

在这里插入图片描述

因为返回的innerAdd会自动的调用toString方法,所以我们可以通过改写toString来实现输出我们想要的结果。

  function add(...outer) {
    function innerAdd(...inner) {
      return add(...outer, ...inner);
    }

    innerAdd.toString = function () {
      let result = 0;
      for (let i = 0; i < outer.length; i++) {
        result += outer[i];
      }
      return result;
    }
    return innerAdd;
  }
  
  console.log(add(1)(2)(3));

在这里插入图片描述

我们用箭头函数和reduce函数来简化代码,最终可以把这个累加器写成下面这样

 function add(...outer) {
    let innerAdd = (...inner) => add(...outer, ...inner);
    innerAdd.toString = () => outer.reduce((pre, cur) => pre + cur);
    return innerAdd;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值