从了解 Rx
至今,我决定抛开 官话
、AI
,以自述的形式向大家,也向着多年后再次回温文章的自己做一个阐释或者说是学习记录,亦或是理解沉淀。
本篇作为第一篇《启蒙》,一起回顾编程范式的编年史,所谓知其然而后知其所以然。
希望你或者是我都会有一份新的收获。
从计算机的演变至今,先辈们创造了各种各样的编程范式,诸如 命令式编程
、函数式编程
、面向对象编程
......
其中更详细且更加官方的内容,可以参考维基百科的 编程范式,这里对于其它编程范式类型也不再做过多的赘述,读者可以自行了解。
在介绍我们的重头戏函数式编程前,我们先行介绍最基础两个编程范式,也是大家最容易迷惑,疑问最多的范式概念:“命令式编程” 和 “声明式编程”,两者可以说是遥相呼应,后者更像是前者的上层抽象;
命令式编程:命令“机器”_如何去做事情_(how)_,这样不管你想要的是什么(what),它都会按照你的命令实现。
声明式编程:告诉“机器”你想要的_是什么(what)_,让机器想出如何去做(how)。
过程导向型编程,好比我们先刷牙,后吃早饭,然后开始工作,更加偏向于过程,举个代码示例:
function equalRandom() {
let a = 2;
let b = Math.random();
if(a>b) {
return true;
} else {
return false;
}
}
看,就是这样,面向过程形式的去 判断定数和随机数的大小
。
结果导向的编程范式,更倾向于告诉你做什么,并不关心怎么去做。
假设下面是一些工具方法的底层抽象封装库:montage.js
// .....
montage.equalRandom = function(value) {
return value > Math.random();
}
那么我们可以在代码中这么去做:
// context
const result = montage.equalRandom(2);
更加的简洁,同时封装性也更高。
强调使用函数解决问题,在此之前我们先来看看维基百科的定义:
函数式编程,或称函数程序设计、泛函编程(英语:Functional programming),是一种编程范型[1],它将电脑运算[2]视为函数[3]运算,并且避免使用程式状态以及可变物件[4]。
可以发现,上述的两个特征也恰好满足“纯函数”的特性:
此函数在相同的输入值时,需产生相同的输出。函数的输出和输入值以外的其他隐藏信息或状态无关,也和由I/O[5]设备产生的外部输出无关。
该函数不能有语义上可观察的函数副作用[6],诸如“触发事件”,使输出设备输出,或更改输出值以外物件的内容等。 ---- from 维基百科
继此,我们继续拓展 montage.js
库中的工具函数:
// ....
montage.doubleElement = function(value) {
return value.map(_ => _*2);
}
到这里,相信你已经对于函数式编程有了一定的了解和认识,不妨花费 2~3
分钟,结合过往写的代码,回顾一下自己写过的函数到底纯不纯,是否具备改善的余地。
关于纯函数部分,这里简单的做个补充,在读完修叔的《JavaScript
函数式编程实践指南》后做个小结:
在显式的数据与数据流中进行了隐式的数据交换或处理;诸如:
console.log
、I/O
、网络、一切改变外部的行为,或者理解为不在本函数职责范围内的行为。
如果函数可以被当作变量或者返回值时,则称这门语言拥有头等函数。可以略作思考,
JavaScript
有头等函数吗?
提到函数式编程,我们可以作为对比参照,来回顾下面向对象编程:
以对象作为程序的基本单元,将程序和数据封装,可以使用继承来提升代码重用和可扩展性。
由此来看,借用《深入浅出 RxJS
》中的话用来收尾对 OOP
和 FP
的比较:
函数式编程中,倾向于数据就是数据,函数就是函数,函数可以处理 数据,也是并不像面向对象的类概念一样把数据和函数封在一起,而是让每个函数都不要去修改原有数据(不可变性),而且通过产生新的数据来 作为运算结果(纯函数)。
关于一些偏激的话术,诸如“ OOP
编程具有缺陷...”等,这里不做讨论,那么随着一些高级语言的扩展后(开始支持函数式),你喜欢哪种编程范式呢?
[1]
编程范型: https://zh.wikipedia.org/wiki/%E7%BC%96%E7%A8%8B%E8%8C%83%E5%9E%8B
[2]
电脑运算: https://zh.wikipedia.org/wiki/%E9%9B%BB%E8%85%A6%E9%81%8B%E7%AE%97
[3]
函数: https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B0
[4]
不可变物件: https://zh.wikipedia.org/wiki/%E4%B8%8D%E5%8F%AF%E8%AE%8A%E7%89%A9%E4%BB%B6
[5]
I/O: https://zh.wikipedia.org/wiki/I/O
[6]
函数副作用: https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B0%E5%89%AF%E4%BD%9C%E7%94%A8