js函数式编程(二)-柯里化
这节开始讲的例子都使用简单的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) => (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!
本博客随笔均为原创,禁止转载,欢迎分享,想获取最新文章,请关注下方微信公众号