js函数式编程(二)-柯里化

这节开始讲的例子都使用简单的TS来写,尽可能作到和es6差异不大,正文以下

咱们在编程中必然须要用到一些变量存储数据,供从此其余地方调用。而函数式编程有一个要领就是最好不要依赖外部变量(固然容许经过参数传递咯),如何解决这个矛盾的问题呢?将函数柯里化`Curry`就能够了,这种技巧可让函数记住一些历史数据,也就是缓存,怎么作呢? 说柯里化以前必须先说一下闭包,由于这是实现柯里化的方法。 javascript

闭包

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`做为局部变量被依赖着就一直存在,那么这个局部变量要是参数是否是也有一样的效果呢,答案是确定的。 java

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

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

柯里化

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

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库还包含了不少已经柯里化的函数。 缓存

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! 闭包

相关文章
相关标签/搜索