《JS函数式编程指南》使用JavaScript
讲述了函数式编程的基本思想,函数式编程有很多优点,比如简洁,消除"副作用"等等。同时它是来源数学理论,可以达到更高的抽象度。
介绍
函数式编程
也叫面向函数编程
,是编程范式的一种,它其实出现得很早,理论基础起源于上个世纪30年代数学界的lambda
演算,属于范畴论
,最早运用这一思想的编程语言是上世纪50年代的Lisp
语言,这门语言在黑客圈极具传奇色彩。
另一种更为大家知道的编程范式就是大名鼎鼎的面向对象编程
(当然,面向“对象”编程,是程序猿的梦想之一)。十年之前,我们接触到的编程教材、技术文章,讲述的几乎都是面向对象编程,编程不使用接口、类、继承
,都不好意思说自己会编程。
函数式编程思想近几年越来越为大家接受和推崇,两大主流语言相继增加了支持函数式编程的特性:
Java8
新增了Lambda
表达式,同时增加了相关应用场景的支持,如Stream
流式处理;
JavaScript
也在ES6
增加了Lambda
表达式,也增加了相关应用场景的支持,如Array
的map, fliter, reduce
操作。同时,JavaScript
的三大框架之一React,今年新增了Hooks特性,支持有状态函数组件,从而完全可以替代类组件。
从大的趋势来看,各大主流语言逐渐趋于支持多种范式,如JavaScript同时也增加了面向对象的特性:类和继承。
函数式编程的特点
函数是一等公民
这是函数式编程一个基本条件,这里并不是说函数有什么优先权,而是:函数和其它数据类型一样,可以赋值给变量、可以作为参数传递、可以作为返回值等等。
根据上面的特点,我们还可以引申出来一些概念:
- 函数嵌套
- 闭包
- 高阶函数
这些JS开发者都很熟悉,也会经常用到,等后面再回过头看看这些特性在函数式编程里面有什么使用场景。
代码示例:
// 嵌套函数,返回函数
function regexCheck(reg) {
return function(str) {
return reg.test(str)
}
}
// 高阶函数
regexCheck(/^(130|131)\d{8}$/)('13012341234')
使用表达式,而不是语句
表达式的特点是:它是一个单纯的运算过程,完成后总是会有运算结果。最常见的表达式就是运算表达式,比如:
const a = 10
const b = a * 10 + 10
函数式编程里的表达式,其实就是把函数当作普通变量来使用:
// 参数函数,返回函数
function ifNot(func) {
return function(x) {
return !func(x)
}
}
// 函数组合
const isHtmlTag = regexCheck(/<\/?\S+>/)
;['hello world', '<script>alert(1)</script>'].filter(ifNot(isHtmlTag))
把函数当作变量一样来运算,代码可以变得很简洁灵活(后续还会接触更多的)。
没有副作用
这里的"副作用"就是Side Effect
,指的就是:函数运行过程中,产生了运算以外的其他结果,比如:修改了全局变量、向数据库写入了数据、发起了网络请求等等。
函数式编程为什么要消除“副作用”,经验丰富的程序员一定知道,系统复杂性和Bug很多时候就是因"副作用"而起:
- 一个全局变量,很多地方都去使用和修改它,你将很难保证它没有被错误地使用。如果还涉及到了多线程,那就大大增加了系统复杂性,你去面试后端岗位,高并发是考察你能力的最重要的点。
- 向数据库写入了数据和发起了网络请求一样,永远是系统中的炸弹,你不知道它什么时候就出现你没有预料到的状况。
当然,我们也不能完全避免副作用,我们要做的是控制它,状态管理器Redux
中就有effects
概念,React Hooks
里面也有effect hook
,目的都是隔离“副作用”。
消除"副作用"有一个常见的方案:不改变状态,即函数调用返回新的值,如:
const serials = ['10', '20', '30']
// 下面的运算不会改变前面的变量
const serialsOpts = serials.concat(['40', '50']).join('/')
引用透明
引用透明其实就是前面特性的衍生特性,说的就是:使用相同的参数调用函数,每次都会得到相同的结果。 我们完全可以用结果代替这个函数表达式,所以叫引用透明。
当一个函数不依赖外部变量和状态时,它就可以满足引用透明,这样的函数我们也叫它纯函数。
它的好处很多:
- 很容易的理解和推导程序。
- 我们还可以很容易地构建测试程序,因为它的运算逻辑是单纯、稳定的。
- 可以任意地并行执行。
总结
函数编程起源于数学的范畴论,理论相当抽象,我还是个初学者,本篇简单介绍了函数式编程的历史和现状,讲述了函数式编程的基本特点。后续我还会继续学习和记录函数式编程的相关理论、常见设计模式和它们的应用。
欢迎交流
个人读书公众号,欢迎交流!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。