这节开始讲的例子都使用简单的TS来写,尽量做到和es6差别不大,正文如下

我们在编程中必然需要用到一些变量存储数据,供今后其他地方调用。而函数式编程有一个要领就是最好不要依赖外部变量(当然允许通过参数传递咯),如何解决这个矛盾的问题呢?将函数柯里化`Curry`就可以了,这种技巧可以让函数记住一些历史数据,也就是缓存,怎么做呢?

说柯里化之前必须先说一下闭包,因为这是实现柯里化的方法。

## 闭包

const fun = () => {
let a = 0;
return () => {
a += 1;
return a;
};
};
const fa = fun();
console.log(fa()); // 1
console.log(fa()); // 2
console.log(fa()); // 3

每次运行这个函数居然结果不一样,why?因为`a`是`fun`函数内部变量,而这个变量又被`fun`返回的函数依赖,`fun()`执行后,fa所指向的那个函数(`fun`的返回值)还在依赖着`a`。根据js的垃圾回收机制,只要`fa`存在,那么`a`就不会被释放,一直在内存中。

进一步想,既然a作为局部变量被依赖着就一直存在,那么这个局部变量要是参数是不是也有同样的效果呢,答案是肯定的。

```javascript
const fun = (a: number) => {
return () => {
a += 1;
return a;
};
};
const fa = fun(1);
console.log(fa()); // 2
console.log(fa()); // 3
console.log(fa()); // 4
```

好,闭包就讲这么多。回到柯里化。

## 柯里化

柯里化由函数闭包实现。我们把上面的例子改一改

```javascript
const fun = (a: number) => (b: number) => {
return a + b
};
const add2 = fun(2);
console.log(add2(2)); // 4
console.log(add2(3)); // 5
console.log(add2(4)); // 6
```

`fun(2)`就是`(b) => b+2`,所以`add2(2)`自然是`4`。以上就是柯里化,参数可以先后传入,全部传完才计算。以上是es6或ts的代码实现,比较简陋。事实上你完全不必要自己去实现一个函数的柯里化。可以使用成熟的库如ramda。ramda库还包含了很多已经柯里化的函数。

```javascript
import { curry } from 'ramda'
const fun = curry((a: number, b: number) => {
return a + b
});
const add2 = fun(2);
console.log(add2(2)); // 4
console.log(add2(3)); // 5
console.log(add2(4)); // 6
```

把一个你要柯里化的函数,原封不动的给curry函数,返回的就是柯里化的函数。但要注意函数参数从左往右的顺序是依次传给柯里化后函数的顺序。have fun!

js函数式编程(二)-柯里化的更多相关文章

  1. 函数式编程之柯里化(curry)

    函数式编程curry的概念: 只传递给函数一部分参数来调用函数,然后返回一个函数去处理剩下的参数. var add = function(x) { return function(y) { retur ...

  2. JS中的反柯里化( uncurrying)

    反柯里化 相反,反柯里化的作用在与扩大函数的适用性,使本来作为特定对象所拥有的功能的函数可以被任意对象所用.即把如下给定的函数签名, obj.func(arg1, arg2) 转化成一个函数形式,签名 ...

  3. JS 浅谈函数柯里化,不明觉厉

    在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.这个技术由 Christopher ...

  4. js bind es5函数柯里化

    绑定函数 bind()最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的this值.常见的错误就像上面的例子一样,将方法从对象中拿出来,然后调用,并且希望this指向原来的对象. 如果不做特 ...

  5. js链式调用 柯里化

    var d = 1; d.add(2).add(3).add(4) //输出10 写出这个add函数 Number.prototype.add = function(x){ return this + ...

  6. JavaScript函数的柯里化(currying)

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/currying.html 什么是js函数的currying /柯里化? 说到js的柯里化,相信很多朋友都会头大.或 ...

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

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

  8. JavaScript ES6函数式编程(二):柯里化、偏应用和组合、管道

    上一篇介绍了闭包和高阶函数,这是函数式编程的基础核心.这一篇来看看高阶函数的实战场景. 首先强调两点: 注意闭包的生成位置,清楚作用域链,知道闭包生成后缓存了哪些变量 高阶函数思想:以变量作用域作为根 ...

  9. Java函数式编程:二、高阶函数,闭包,函数组合以及柯里化

    承接上文:Java函数式编程:一.函数式接口,lambda表达式和方法引用 这次来聊聊函数式编程中其他的几个比较重要的概念和技术,从而使得我们能更深刻的掌握Java中的函数式编程. 本篇博客主要聊聊以 ...

随机推荐

  1. express使用post方法

    express有get.post和在路由后面跟参数,这三种接参方式,这篇文章我主要记录post使用方法 1.json解析中间件(body-parser) cnpm install body-parse ...

  2. 13.Python略有小成(装饰器,递归函数)

    Python(装饰器,递归函数) 一.开放封闭原则 ​ 软件面世时,不可能把所有的功能都设计好,再未来的一两年功能会陆续上线,定期更新迭代,软件之前所用的源代码,函数里面的代码以及函数的调用方式一般不 ...

  3. Angular.js思维导图

    AngularJS的四大特性的思维导图如下: 将AngularJS应用于工作:其思维导图如下: AngularJS服务思维导图:

  4. Linux常用命令(补充)--其他

    其他1)记录命令历史(1)!! (连续两个”!”),表示执行上一条指令:(2)!n(这里的n是数字),表示执行命令历史中第n条指令,例如”!100”表示执行命令历史中第100个命令:(3)!字符串(字 ...

  5. 本机和虚拟机互联 设置静态IP vmware 虚拟网络 桥接 NAT 仅主机 自定义

  6. IBM Websphere MQ常用命令及常见错误

    MQSC: MQ Script Command  (不区分大小写) 注明: 下面命令行中的队列管理器名字,队列名字分别用QmgrName, QName替代. 下面标蓝色的,都需要根据实际配置更改! 打 ...

  7. Python多继承C3算法

    Python3 多继承的MRO算法选择.MRO(Method Resolution Order):方法解析顺序. Python3 只保留了C3算法! C3算法解析: 1.C3算法解析 C3算法:MRO ...

  8. 自动化测试资源(二):火狐浏览器驱动 geckodriver

    geckodriver:https://github.com/mozilla/geckodriver geckodriver 历史版本下载列表:https://github.com/mozilla/g ...

  9. MiniProfiler NET Core

    MiniProfiler 来分析 ASP.NET Core 应用 它会把结果直接放在页面的左下角,随时可以点击查看:这样的话就可以感知出你的程序运行的怎么样:同时这也意味着,在你开发新功能的同时,可以 ...

  10. NET Core 2.0 使用支付宝

    ASP.NET Core 2.0 使用支付宝PC网站支付   前言 最近在使用ASP.NET Core来进行开发,刚好有个接入支付宝支付的需求,百度了一下没找到相关的资料,看了官方的SDK以及Demo ...