ECMAScript 函数式编程
ES6 函数式编程变得更方便、更强大
JavaScript 语言从一诞生,就具有函数式编程的烙印。它将函数作为一种独立的数据类型,与其他数据类型处于完全平等的地位。在 JavaScript 语言中,你可以采用面向对象编程,也可以采用函数式编程。有人甚至说,JavaScript 是有史以来第一种被大规模采用的函数式编程语言。
ES6 的种种新增功能,使得函数式编程变得更方便、更强大。本章介绍 ES6 如何进行函数式编程。
柯里化(currying)指的是将一个多参数的函数拆分成一系列函数,每个拆分后的函数都只接受一个参数(unary)。
上面代码中,函数add
接受两个参数a
和b
。
柯里化就是将上面的函数拆分成两个函数,每个函数都只接受一个参数。
上面代码中,函数add
只接受一个参数a
,返回一个函数f
。函数f
也只接受一个参数b
。
函数合成(function composition)指的是,将多个函数合成一个函数。
上面代码中,compose
就是一个函数合成器,用于将两个函数合成一个函数。
可以发现,柯里化与函数合成有着密切的联系。前者用于将一个函数拆成多个函数,后者用于将多个函数合并成一个函数。
参数倒置(flip)指的是改变函数前两个参数的顺序。
上面代码中,如果按照正常的参数顺序,10 除以 5 等于 2。但是,参数倒置以后得到的新函数,结果就是 5 除以 10,结果得到 0.5。如果原函数有 3 个参数,则只颠倒前两个参数的位置。
参数倒置的代码非常简单。
执行边界(until)指的是函数执行到满足条件为止。
上面代码中,第一段的条件是执行到x
大于 100 为止,所以x
初值为 0 时,会一直执行到 101。第二段的条件是执行到等于 5 为止,所以x
最后的值是 5。
执行边界的实现如下。
上面代码的关键就是,如果满足条件就返回结果,否则不断递归执行。
队列(list)操作包括以下几种。
head
: 取出队列的第一个非空成员。
last
: 取出有限队列的最后一个非空成员。
tail
: 取出除了“队列头”以外的其他非空成员。
init
: 取出除了“队列尾”以外的其他非空成员。
下面是例子。
这些方法的实现如下。
合并操作分为concat
和concatMap
两种。前者就是将多个数组合成一个,后者则是先处理一下参数,然后再将处理结果合成一个数组。
这两种方法的实现代码如下。
配对操作分为zip
和zipWith
两种方法。zip
操作将两个队列的成员,一一配对,合成一个新的队列。如果两个队列不等长,较长的那个队列多出来的成员,会被忽略。zipWith
操作的第一个参数是一个函数,然后会将后面的队列成员一一配对,输入该函数,返回值就组成一个新的队列。
下面是例子。
上面代码中,zipWith
方法的第一个参数是一个求和函数,它将后面三个队列的成员,一一配对进行相加。
这两个方法的实现如下。