什么是函数柯里化

在计算机科学中,柯里化(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)小实践的更多相关文章

  1. 函数柯里化(Currying)示例

    ”函数柯里化”是指将多变量函数拆解为单变量的多个函数的依次调用, 可以从高元函数动态地生成批量的低元的函数.可以看成一个强大的函数工厂,结合函数式编程,可以叠加出很BT的能力.下面给出了两个示例,说明 ...

  2. Swift函数柯里化(Currying)简谈

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面简单说说Swift语言中的函数柯里化.简单的说就是把接收多 ...

  3. 前端开发者进阶之函数柯里化Currying

    穆乙:http://www.cnblogs.com/pigtail/p/3447660.html 在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接 ...

  4. 偏函数应用(Partial Application)和函数柯里化(Currying)

    偏函数应用指的是固化函数的一个或一些参数,从而产生一个新的函数.比如我们有一个记录日志的函数: 1: def log(level, message): 2: print level + ": ...

  5. 应用js函数柯里化currying 与ajax 局部刷新dom

    直接上代码吧 最近读javascript核心概念及实践的代码 感觉很有用 备忘. <div id="request"></div> <script t ...

  6. Javascript函数柯里化(curry)

    函数柯里化currying,是函数式编程非常重要的一个标志.它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去.我们依靠这个特性编写很多优雅酷炫的代 ...

  7. 深入理解javascript函数进阶系列第二篇——函数柯里化

    前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...

  8. JS中的柯里化(currying)

    何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参 ...

  9. 简单粗暴详细讲解javascript实现函数柯里化与反柯里化

    函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...

随机推荐

  1. TimeUtils

    public class TimeUtils { public static final int YEAR = 0; public static final int MONTH = 1; public ...

  2. HDU 5172 GTY's gay friends (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5172 题意: 给你一个n个数的数组,m次询问,询问在[L, R] 这个区间里面有没有 [1, R-L+ ...

  3. 无法绕开的cut, awk, sed命令

    linux命令的选项和选项后面的值的方式: 如果用 短选项, 选项值就放在短选项的后面, 如果用长选项, 值就用等于的方式. 最重要的是, 短选项后面的值, 跟短选项之间, 可以用空格, 也可以紧接着 ...

  4. CStatic中保持图形比例不变,尽量填充控件空间的代码

    CStatic中保持图形比例不变,尽量填充控件空间的代码 先获取控件的高.宽,然后获取图像的高.宽,测试需要调整高还是调整宽 void CImagePreviewStatic::DrawItem(LP ...

  5. UDP信号驱动IO

    SIGIO信号 信号驱动式I/O不适用于TCP套接字, 因为产生的信号过于频繁且不能准确判断信号产生的原因. 设置信号驱动需把sockfd的非阻塞与信号驱动属性都打开 server sockfd单独提 ...

  6. 解锁 HTTPS原理

    From今日头条:https://www.toutiao.com/a6534826865792647693/?tt_from=weixin&utm_campaign=client_share& ...

  7. java 泛型深入

    1.<? extends E> <? extends E> 是 Upper Bound(上限) 的通配符,用来限制元素的类型的上限.   赋值 List<? extend ...

  8. linux系统中的基础监控(硬盘,内存,系统负载,CPU,网络等)

      Linux系统常见日常监控 系统信息 查看 CentOS 版本号:cat /etc/redhat-release 综合监控 nmon 系统负载 命令:w(判断整体瓶颈) 12:04:52 up 1 ...

  9. Vue2+VueRouter2+webpack 构建项目实战(四)接通api,先渲染个列表

    Vue2+VueRouter2+webpack 构建项目实战(四)接通api,先渲染个列表:  Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述

  10. dp(动态规划之最佳路径+dfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1078 FatMouse and Cheese Time Limit: 2000/1000 MS (Java/Ot ...