二. Functional Programming
函数式编程 是Rx最重要的概念之一,学会FP 再上手Rx就不难了.
函数式编程 同时可以说是16年来的显学,各个语言都有加强对FP的支持.
1.Functional Programming 是什么
函数式编程(Functional Programming) 是一种编程思想.
函数式编程的核心思想就是做运算处理,从 函数 的角度来思考问题.
// (5 + 6) - 1 * 3
// 写成如下
const add = (a, b) => a + b
const mul = (a, b) => a * b
const sub = (a, b) => a - b
sub(add(5, 6), mul(1, 3))
- 每一步骤包装成一个个不同的函数
- 调用函数,组合完成复杂的计算
这就是最简单的 函数式编程.
就像 面向对象 Object-oriented Programming(OOP)一样, 一种编程的方法论,告诉我们如何思考和解决问题.
同时函数更语义话,读函数名即知其效果.
2.什么样的语言可以使用 Functional Programming 思想
函数为一等公民(First Class)
指,拥有和其他变量类型同等的地位.能被赋值给变量,能作为参数,能作为返回值.
3.Functional Programming 的特点
(1) Expression, no Statement 使用表达式
Functional Programming 都是 表达式 (Expression) 不會是 称述式(Statement).
表达式 是一个运算过程, 一定会有返回值, 例如执行一个function
add(1,2)
陈述式 则表现某种行为, 例如给一个变量赋值
a = 1;
有时候表达式也可能是合法的陈述式,这里只讲了基本的判断方式.更深入的了解区别, Expressions versus statements in JavaScript
这一块基本没看懂.
(2) Pure Function 必须是纯函数
纯函数 是指 一个函数传入相同的参数并执行,永远返回相同的值,并且没做任何额外操作.
var arr = [1, 2, 3, 4, 5];
arr.slice(0, 3); // [1, 2, 3]
arr.slice(0, 3); // [1, 2, 3]
arr.slice(0, 3); // [1, 2, 3]
// 不管执行多少次,返回值都相同,并且除了返回值,没有任何额外操作.
// 所以slice是一个 纯函数
var arr = [1, 2, 3, 4, 5];
arr.splice(0, 3); // [1, 2, 3]
arr.splice(0, 3); // [4, 5]
arr.slice(0, 3); // []
// splice 每次执行都影响了arr本身,做了额外操作,并且导致每次结果不同
// 所以splice不是一个 纯函数
修改全局变量, 修改传入参数的值,甚至执行console.log,都不能算纯函数
纯函数 不管外部环境如何,只要参数相同,其返回值必定相同.这种不依赖任何外部状态,只依赖传入参数的特性也称为 引用透明
(3) 可利用参数保存状态
function findIndex(arr, predicate, start = 0) {
if (0 <= start && start < arr.length) {
if (predicate(arr[start])) {
return start;
}
return findIndex(arr, predicate, start+1);
}
}
findIndex(['a', 'b'], x => x === 'b'); // 找陣列中 'b' 的 index
findeIndex
中第三个参数就是利用参数保存状态
4.Functional Programming 有什么优势
可读性高,透过一系列函数封装,代码能非常简洁易懂
可维护性高,不依赖外部环境,不影响外部环境,一个函数维持一小个功能,可直接单独修改。
易于并行/平行的处理, 因为只运算,不碰I/O,没有额外操作,所以不用担心锁死
[9, 4].concat([8, 7]) // 合并
.sort() // 排序
.filter(x => x > 5) // 过滤出大于5的.
第三条 易于并行/平行的处理 没懂,意思是都是同步操作所以不担心锁死,所以方便处理并行操作?
5.总结
Functional Programming 的特性,必须表达式,必须是纯函数,易于参数保存
Functional Programming 的优势,可读性高,可维护性强,易于并行/平行的处理.