什么是函数柯里化

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。 举个例子,假设程序员A是个妻管严,工资悉数上交给妻子,为了买一个心爱的键盘函数柯里化(Currying)小实践

程序员A每天都偷偷藏几毛钱,打算年底买个键盘,因此程序员A写了以下这个方法用来统计年终一共凑了多少钱,方法如下:


  1. /**

  2. * @description 统计金额

  3. * @return {number}

  4. */

  5. function countMoney() {

  6.  let money = 0

  7.  // 温馨提示:arguments是所接收的所有参数组成的类数组,不懂的需要搜一搜补补知识啦

  8.  for (let i = 0; i < arguments.length; i++) {

  9.    money += arguments[i]

  10.  }

  11.  return money

  12. }

  13. // 藏了一年的账本记录的数据

  14. const records = [1, 1, 2, 2, 3, 3, 4, 4]

  15. // 把全部数据都输入进行计算

  16. countMoney(1, 1, 2, 2, 3, 3, 4, 4)

上面代码所呈现的方法,是最直接的计算方法,其不方便的地方在于,程序员A还要拿个小本本把每天存了多少钱先记录下来!!!万一这个本子被发现那就少不了跪键盘了,极度不安全。

函数柯里化(Currying)小实践

更安全地藏私房钱

实际上,每天记录下当前的数据是不灵活的,而函数柯里化则有效地解决了这个问题。 我们想要这样存储我们的私房钱


  1. // 2018-01-01 存了1毛钱

  2. countMoney(1)

  3. // 2018-01-02 存了2毛钱

  4. countMoney(2)

  5. // 2018-01-03 存了3毛钱

  6. countMoney(3)

  7. // 2018-01-04 存了4毛钱

  8. countMoney(4)

  9. //一年以后

  10. // 统计这笔巨额存款

  11. countMoney()

上述的这种方法中,我们不关心数据的存储记录,我们只需要每天往存钱罐里面塞钱,然后年底取出来就是一个总和。再也不担心留下小本本作为证据了!

函数柯里化代码的实现


  1. /**

  2. * @description countMoney为立即执行函数,返回的结果是另一个函数

  3. */

  4. const countMoney = (function () {

  5.  let money = 0

  6.  let args = []

  7.  const res = function () {

  8.    if (arguments.length === 0) {

  9.      for (let i = 0; i < args.length; i++) {

  10.        money += args[i]

  11.      }

  12.      return money

  13.    } else {

  14.      // arguments 是个类数组来着,应该用展开符展开才能push进去

  15.      args.push(...arguments)

  16.      return res

  17.    }

  18.  }

  19.  return res

  20. })()

  21. // 2018-01-01 存了1毛钱

  22. countMoney(1)

  23. // 2018-01-02 存了2毛钱

  24. countMoney(2)

  25. // 2018-01-03 存了3毛钱

  26. countMoney(3)

  27. // 2018-01-04 存了4毛钱

  28. countMoney(4)

  29. //一年以后

  30. // 统计这笔巨额存款 输出结果为 10

  31. console.log(countMoney())

  32. // 你还可以装逼地进行花式统计,结果同样是10

  33. countMoney(1)(2)(3)(4)()

分析代码

实际上,在JavaScript的很多思想和设计模式中,闭包是个很常见且很重要的东西,上述的代码中,本质上就是利用了闭包。 该函数是个立即执行函数,返回了一个新函数,而这个新函数实际上就是一个闭包,这个新函数把每次接收到的参数都存储起来, 并且继续返回一个新函数,当发现某次调用的时候没有传入参数,那就意味着要进行数据统计,从而把之前存储的数据一次性拿 出来计算,最后返回计算结果。其流程如下:函数柯里化(Currying)小实践

总结

所谓的函数柯里化,亦或者在开发中涉及到的其他一些概念,例如闭包、单例模式、观察者模式等等都好,我们需要关注的点在于掌握 这些模式或者概念中的代码设计思想,从而更好地服务于我们的业务开发,让我们的代码更健壮、灵活、高效。


作者:nextBoy

https://segmentfault.com/a/1190000015957944


函数柯里化(Currying)小实践

相关文章: