函数柯里化(Currying)小实践
什么是函数柯里化
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。
举个例子,假设程序员A是个妻管严,工资悉数上交给妻子,为了买一个心爱的键盘
程序员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还要拿个小本本把每天存了多少钱先记录下来!!!万一这个本子被发现那就少不了跪键盘了,极度不安全。
更安全地藏私房钱
实际上,每天记录下当前的数据是不灵活的,而函数柯里化则有效地解决了这个问题。
我们想要这样存储我们的私房钱
// 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的很多思想和设计模式中,闭包是个很常见且很重要的东西,上述的代码中,本质上就是利用了闭包。
该函数是个立即执行函数,返回了一个新函数,而这个新函数实际上就是一个闭包,这个新函数把每次接收到的参数都存储起来,
并且继续返回一个新函数,当发现某次调用的时候没有传入参数,那就意味着要进行数据统计,从而把之前存储的数据一次性拿
出来计算,最后返回计算结果。其流程如下:
总结
所谓的函数柯里化,亦或者在开发中涉及到的其他一些概念,例如闭包、单例模式、观察者模式等等都好,我们需要关注的点在于掌握
这些模式或者概念中的代码设计思想,从而更好地服务于我们的业务开发,让我们的代码更健壮、灵活、高效。
函数柯里化(Currying)小实践的更多相关文章
- 函数柯里化(Currying)示例
”函数柯里化”是指将多变量函数拆解为单变量的多个函数的依次调用, 可以从高元函数动态地生成批量的低元的函数.可以看成一个强大的函数工厂,结合函数式编程,可以叠加出很BT的能力.下面给出了两个示例,说明 ...
- Swift函数柯里化(Currying)简谈
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面简单说说Swift语言中的函数柯里化.简单的说就是把接收多 ...
- 前端开发者进阶之函数柯里化Currying
穆乙:http://www.cnblogs.com/pigtail/p/3447660.html 在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接 ...
- 偏函数应用(Partial Application)和函数柯里化(Currying)
偏函数应用指的是固化函数的一个或一些参数,从而产生一个新的函数.比如我们有一个记录日志的函数: 1: def log(level, message): 2: print level + ": ...
- 应用js函数柯里化currying 与ajax 局部刷新dom
直接上代码吧 最近读javascript核心概念及实践的代码 感觉很有用 备忘. <div id="request"></div> <script t ...
- Javascript函数柯里化(curry)
函数柯里化currying,是函数式编程非常重要的一个标志.它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去.我们依靠这个特性编写很多优雅酷炫的代 ...
- 深入理解javascript函数进阶系列第二篇——函数柯里化
前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...
- JS中的柯里化(currying)
何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参 ...
- 简单粗暴详细讲解javascript实现函数柯里化与反柯里化
函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...
随机推荐
- Otto
导入依赖:implementation 'com.squareup:otto:1.3.8'1定义一个类继承Bus,并且设置单列模式注册和声明订阅者发送事件,最后解除注册与EventBus相同Event ...
- C/C++中动态内存分配
代码段:用来存放程序执行代码的一块内存区域.这部分内存大小在程序运行前已经知道,通常属于只读,其中包括只读的字符串常量,不可改变 BBS段:用来存放存放程序中未初始化的全局变量及静态变量,属于静态内存 ...
- qbzt day3 上午
内容提要 堆 lca(最近公共祖先) st表 hash 并查集 树状数组 线段树 数据结构 1.堆 Priority_queue 他滋兹:插入删除查询最大值(最小值) 分为大根堆小根堆 2.LCA 首 ...
- 协议-TCP:TCP
ylbtech-协议-TCP:TCP 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793 ...
- java poi 导入导出Excel xsl xslx
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import ...
- Git 实践
最近也学习了Git的相关知识,现通过一个实例来记录Git使用流程,也方便日后使用. git的基础学习: https://www.yiibai.com/git/git-quick-start.html ...
- 在centos7.4 nginx mysql php部署 thinkphp5.0 项目
系统 centos7 环境 php 7.1.3 nignx 1.12.2 mysql 5.5.6 我是通过lnmp 集成环境安装 fastcgi.conf 末尾添加 vim fastcig.conf ...
- hbase迁移快照ExportSnapshot时遇到的错
1.Cannot allocate memory 报错信息: Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x ...
- package__init__用途
baidu包,假设在baidu包下有N个模块,分别是baidu1.py.baidu2.py,baidu3.py, baiduHq.py(baidu1.py,baidu2.py,baidu3.py模块代 ...
- final关键字的案例
package com.company.java.oop.cls; class ClassF { // static ClassF instance =new ClassF(); static { S ...