函数柯里化(Currying)小实践

2018-08-10 admin

什么是函数柯里化

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

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

/**
 * @description 统计金额
 * @return {number}
 */
function countMoney() {
  let money = 0
  // 温馨提示:arguments是所接收的所有参数组成的类数组,不懂的需要搜一搜补补知识啦
  for (let i = 0; i < arguments.length; i++) {
    money += arguments[i]
  }

  return money
}
// 藏了一年的账本记录的数据
const records = [1, 1, 2, 2, 3, 3, 4, 4]
// 把全部数据都输入进行计算
countMoney(1, 1, 2, 2, 3, 3, 4, 4)

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

更安全地藏私房钱

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

// 2018-01-01 存了1毛钱
countMoney(1)
// 2018-01-02 存了2毛钱
countMoney(2)
// 2018-01-03 存了3毛钱
countMoney(3)
// 2018-01-04 存了4毛钱
countMoney(4)
//一年以后
// 统计这笔巨额存款
countMoney()

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

函数柯里化代码的实现

/**
 * @description countMoney为立即执行函数,返回的结果是另一个函数
 */
const countMoney = (function () {
  let money = 0
  let args = []
  const res = function () {
    if (arguments.length === 0) {
      for (let i = 0; i < args.length; i++) {
        money += args[i]
      }
      return money
    } else {
      // arguments 是个类数组来着,应该用展开符展开才能push进去
      args.push(...arguments)
      return res
    }
  }
  return res
})()

// 2018-01-01 存了1毛钱
countMoney(1)
// 2018-01-02 存了2毛钱
countMoney(2)
// 2018-01-03 存了3毛钱
countMoney(3)
// 2018-01-04 存了4毛钱
countMoney(4)
//一年以后
// 统计这笔巨额存款 输出结果为 10
console.log(countMoney())
// 你还可以装逼地进行花式统计,结果同样是10
countMoney(1)(2)(3)(4)()

分析代码

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

总结

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

原文链接:https://segmentfault.com/a/1190000015957944

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-37681.html

文章标题:函数柯里化(Currying)小实践

相关文章
常用的Javascript函数
软件界面采用WEB界面,因此要用到Javascript.一些通用JS函数整理了下:) &#x2F;*判断浏览器版本*&#x2F; var w3c = (document.getElementById) ? true : false; var...
2015-11-11
vue使用watch 观察路由变化,重新获取内容
问题背景: 点击用户头像 =&gt; 进入用户个人中心,在用户个人中心里点击其他用户的头像,我希望显示被点击用户的个人中心,但只看到了路由参数在发生变化,页面内容并没有更新。如图: 页面代码如下: &lt;script&gt; exp...
2017-03-13
JavaScript中字符串分割函数split用法实例
本文实例讲述了JavaScript中字符串分割函数split用法。分享给大家供大家参考。具体如下: 先来看下面这段代码: &lt;script type=&quot;text&#x2F;javascript&quot;&gt; var st...
2017-03-22
JS常见创建类的方法小结【工厂方式,构造器方式,原型方式,联合方式等】
本文实例讲述了JS常见创建类的方法。分享给大家供大家参考,具体如下: Javascript是一种基于对象的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有Class。(不过,ES6引...
2017-04-05
js使用split函数按照多个字符对字符串进行分割的方法
本文实例讲述了js使用split函数按照多个字符对字符串进行分割的方法。分享给大家供大家参考。具体分析如下: js中的split()函数可以对字符串按照指定的符号进行分割,但是如果字符串中存在多个分割符号,js的split()函数是否还可以...
2017-03-21
IE7浏览器窗口大小改变事件执行多次bug及IE6/IE7/IE8下resize问题
本文主要通过代码示例给大家介绍IE7浏览器窗口大小改变事件执行多次bug及IE6/IE7/IE8下resize问题;分步介绍,先给大家介绍IE7浏览器窗口大小改变事件执行多次bug,具体问题分析及解决方案请看下文。 var resizeTi...
2017-03-29
2015 年, HTML5 和 IP 化
HTML5 2010 年 4 月,乔布斯发表了一篇公开信叫做 “Thoughts on Flash” 。里面提到 HTML5 必将统治 Web ( HTML5 will win )。 的确, HTML5 为 Web 带来更丰富的表现和功能。...
2015-11-12
js实现时间显示几天前、几小时前或者几分钟前的方法集锦
这里汇总了js实现时间显示几天前、几小时前或者几分钟前的常见方法。分享给大家供大家参考。具体如下: 方法一: 个人做法是保存时间戳,然后在前端用jq插件做转换,比如 smart-time-ago 方法二: (通过freemarker模板)如...
2017-03-24
javascript实现控制文字大中小显示
部分网站内容页通常会看到有控制文字分别以 大,中,小 三种方式显示,下面就把这个小功能做一下记录,对提高网站用户体验度还是有一些帮助的哦! &lt;html&gt; &lt;head&gt; &lt;meta http-equiv=&q...
2017-03-23
优化RequireJS项目的相关技巧总结
本文将演示如何合并与压缩一个基于RequireJS的项目。本文中将用到苦干个工具,这其中就包括Node.js。 因此,如果你手头上还没有Node.js可以点击此处下载一个。 动机 关于RequireJS已经有很多文章介绍过了。这个工具可以将...
2017-03-27
回到顶部