前言
学习函数式编程,首先要了解函数式编程相关的概念。
一、函数是一等公民
1. 一等公民的定义
根据维基百科,编程语言中一等公民的概念是由英国计算机学家Christopher Strachey提出来的,时间则早在上个世纪60年代。但是他并没有严格的给出一等公民的定义。 关于一等公民的定义,在《Programming Language Pragmatics》书中给出了答案。
In general, a value in a programming language is said to have first-class status if it can be passed as a parameter, returned from a subroutine, or assigned into a variable.
在编程语言中,一等公民可以作为函数参数,可以作为函数返回值,也可以赋值给变量。
2. 为什么说函数是一等公民
在JavaScript中,函数可以使用函数表达式的方式进行定义,因此,函数可以存储在变量中;因为ECMAScript中函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回(闭包)。
-
把函数赋值给变量
代码如下(示例):
// 定义匿名函数,然后把函数赋值给变量 let fn = function () { console.log("Hello First-class Function") } fn() // 把函数保存到其他数据结构,如Object中 const student = { name: "Alison", age: 27, study: function () { return "Study" } }
二、高阶函数(Higher-order function)
1. 什么是高阶函数
-
高阶函数
* 可以把函数作为参数传递给另一个函数* 可以把函数作为另一个函数的返回结果 -
函数作为参数
代码如下(示例):
// forEach function forEach (array, fn) { for (let i = 0; i < array.length; i++) { fn(array[i]) } } // filter function filter (array, fn) { let results = [] for (let i = 0; i < array.length; i++) { if (fn(array[i])) { results.push(array[i]) } } return results } -
函数作为返回值
代码如下(示例):
function makeFn () { let msg = 'Hello function' return function () { console.log(msg) } } // makeFn()(),与下面的调用方式等价 const fn = makeFn() fn()
2. 使用高阶函数的意义
- 抽象可以帮我们屏蔽细节,只需要关注与我们的目标
- 高阶函数是用来抽象通用的问题
3. 常用高阶函数
- forEach
- map
- filter
- every
- some
- find/findIndex
- reduce
- sort
- ……
详情参见:数组(Array)的常用方法
三、闭包(closure)
1. 闭包的目的
- 为了设计私有的方法和变量。
2. 什么是闭包,为什么要用它?
- 闭包是指有权访问另一个函数作用域中变量的函数。
3. 创建闭包的最常见的方式
-
就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。
代码如下(示例):
// 根据对象中的某个属性,进行排序 function createComparisonFunction(propertyName) { return function(object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 > value1 ) { return 1 } else if (value1 < value1) { return -1 } else { return 0 } } }
4. 闭包的特性
- 函数内再嵌套函数;
- 内部函数可以引用外层的参数和变量;
- 参数和变量不会被垃圾回收机制回收。
5. 闭包的优缺点
- 优点
- 可以避免全局变量的污染。
- 利用闭包可以突破作用链域。
- 缺点 闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
总结
函数是一等公民是高阶函数、柯里化等的基础。熟知高阶函数、闭包等,有利于我们学好函数式编程。