函数式编程是一种编程范式,也就是如何编写程序的方法论,其它的编程范式还有面向对象编程,过程化编程等。函数式编程并非一个新兴的概念,而是一个存在久远的概念,随着React的兴起,函数式编程的概念又火了起来,Rxjs、lodash等库都使用了函数式编程的思想。javascript
这个系列会从什么是函数式编程提及,讨论函数式编程的优缺点,如何使用函数式编程编写优雅的代码,最后会探讨函数式编程在Javascript中的一些最佳实践。java
解释什么是函数式编程并非个容易的事情,我也是在尝试着学习和理解。函数式编程不是用function来编程,而是一种如何使用function,才能使它具有函数式的一种方法。要了解怎么使用函数,首先咱们须要了解什么是函数。编程
这里简单回顾一下初中的数学知识,当咱们看待一个函数时,它可能长这样 y = f(x)
f(x) = 2x2 + 3
能够看出函数的基本特色在于它有一个或多个输入值,并进行必定的计算,而且获得一个返回值。函数式编程中有一个术语叫作态射,来描述输入值和输出值的关系。缓存
这里简单讨论下函数和程序的区别,这也是函数式编程的一大特性。程序是一系列指令的集合,它可能有输入值也可能没有,它可能有输出值也可能没有。而函数是接收输入值并经过计算返回输出值。bash
函数式编程的一大特色就是咱们应该尽可能的使用函数而非程序,固然在实际的开发中咱们不可避免的要进行I/O操做,可是若是你的计划是使用函数式编程,那么在开发中就应该尽量多的使用函数,而不是程序。闭包
这是函数式编程的一个重要概念,函数与其余数据类型同样,处于平等地位,能够赋值给其余变量,也能够做为参数,传入另外一个函数,或者做为别的函数的返回值。并发
Javascript自己不是纯的函数式编程语言,能够说是一个多范式的编程语言,可是因为其函数是一等公民特性,咱们能够把函数做为参数进行传递,也能够将函数做为函数的返回值等特性,使得Javascript能够进行函数式编程。app
同时这个特性是函数式编程的一些核心内容,好比闭包、高阶函数、柯里化等特性的基础编程语言
回到上面那个函数,根据其输入输出的值,能够造成以下的图像:函数式编程
经过这个图咱们能够得出两个结论:1. 函数必定有输入和输出值。 2. 函数对于相同的输入值返回相同的输出值,这个特性称为引用透明性。
引用透明性带来的巨大好处在于并发代码和结果可缓存,并发的问题在于对于全局变量的使用,须要引入锁机制来管理全局变量的使用,可是引用透明性只依赖入餐,因此线程能够自由运行。结果的可缓存也是显而易见的,对于一个输入其对应的输出也是惟一的。因此该输入的结果是能够缓存的。
在引用透明性的基础上咱们能够定义纯函数,纯函数具备引用透明性,同时任何外部变量不会影响函数内部运算的结果,同时函数内部的运算也不会影响到外部变量的值。
纯函数给咱们带来的好处在于代码的可测试性的加强,当咱们测试一个函数时,咱们会用输入和指望的正确输出值来验证一个函数的正确性,可是当屡次测试经过以后,是否就能够说咱们的函数是正确的,这个是不必定。若是外部的变量被应用在了函数的运算中,那么当外部变量发生改变时,函数的计算结果也会变得不符合预期。同理,函数改变外部的值也会致使代码的没法测试。
与声明式编码相对应的是命令式代码,意思就是,咱们经过编写一条又一条指令去让计算机执行一些动做,这其中通常都会涉及到不少繁杂的细节。
而声明式就是,咱们经过写表达式的方式来声明咱们想干什么,而不是经过一步一步的指示。
举个遍历的例子,命令式编程的写法是:
var array = [1,2,3];
for(var i = 0; i < array.length; i++){ console.log(array[i])
}复制代码
而声明式的写法是:
array = [1, 2, 3];
array.forEach((item) => { console.log(item); })复制代码
声明式的好处在于代码的编写更清晰简洁,在forEach函数为纯函数的前提下,咱们不用关心函数的内部是如何实现的,开发者只须要关注眼前的事情。
函数式编程根据上述的几个特性,具备如下几个优点:1. 代码的可读性更强 2. 代码的可测试性更强 3. 易于编写可缓存的代码 4. 易于并发
因为函数式编程采用声明式的代码,因此代码的可读性更强,举个例子,当咱们进行一个这样(1 + 2) * 3 - 4
的计算时,咱们可能会写成subtract(multiply(add(1,2), 3), 4)
,对其进行声明式的改造 add(1,2).multiply(3).subtract(4)
这样咱们就能够直观的看出这句表达式的含义了。
这个优点是纯函数带来的,函数与外部变量的隔离使得测试只用关心函数内部逻辑,更易进行单元测试。
这两个优点是函数的引用透明性带来的,这里再也不赘述。
首先清楚地理解什么是函数:它不只仅是一个语句或者操做的集合,并且须要一个或多个输入(理想状况下只需一个!)和一个输出。
函数是一等公民的这个特性是函数式编程的不少特性的基础,也是Javascript语言函数式编程的基础。
引用透明性和纯函数使得函数更加易于测试,同时更易于并发编程和函数的缓存。
声明式表达使得函数更易理解。
下一章咱们会开始讨论如何使用函数式的思想进行编程。