Javascript函数式编程

纯函数

Side Effect, 副作用

非纯函数会产生副作用。我们一般调用一个函数,是要得到一个返回值,或者处理一些数据。但是如果这个函数在给你返回结果之后,影响了其他对象的状态,包括传入参数,甚至一些全局变量,那么我们就说这个函数又Side Effect,副作用。

所谓纯函数,就是不论你调用他多少次,他都会给你返回相同的结果,并且不会改变其他的变量的状态。

非纯函数在易读性易理解方面,是没有纯函数强的。因为我们需要记住每一次调用非纯函数后产生的各种状态转化,这就增加了程序阅读的难度。

非纯函数,会增加代码阅读时的困难。但这并不是说明我们要远离非纯函数,非纯函数是程序的必备部分。

构造一个纯函数

一个比较直接的方式,传入所有依赖的状态并做copy。这可能带来开销问题,内存,时间等等。

什么时候选择写一个纯函数,是要根据场景来判断的。纯函数不是解决任何问题的最好方法。

函数组合

函数组合是为了避免产生连续的纯函数调用时,依赖的中间状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1
function sum(x,y) {
return x + y;
}
function multi(x,y) {
return x * y;
}

var z = multi(3,4);
z = sum(z,5);

// 手动组合2
var z = sum(multi(3,4),5);

// 手动组合3
function multiAndSum(x,y,z) {
return sum(multi(x,y),z);
}
multiAndSum(3,4,5);

组合的函数

1
2
3
4
5
6
7
8
9
function compose(fn1, fn2) {
return function comp() {
var args = [].slice.call(arguments);
refurn fn2(fn1(args.shift(), args.shift()), args.shift());
}
}

var multiAndSum = compose2(multi, sum);
multiAndSum(3,4,5);

Immutability

1
2
3
4
5
6
7
8
9
10
11
12
13
var x = 2;
x++; // allowed

const y = 3;
y++; //not allowed

const z = [4,5,6];
z = 10; //not allowed
z[0] = 0; // allowed

const w = Object.freeze([4,5,6])
w = 10; /not allowed
w[0] = 10; /not allowed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function doubleThemMutable(list) {
for(var i = 0; i < list.length; i++>) {
list[i] = list[i] * 2;
}
}
var arr = [3,4,5];
doubleThemMutable(arr);
arr; // [6,8,10];
function doubleThemImmutable(list) {
var newList = [];
for(var i = 0; i < list.length; i++>) {
newList[i] = list[i] * 2;
}
}
var arr = [3,4,5];
var arr2 = doubelThemImmutable(arr);
arr; // [3,4,5]
arr2; //[6,8,10]