hi~ 我是
无言非影
, 很高兴在这里分享我的学习历程。
关于 函数式编程 整理的一些笔记,都统一记录在: 函数式编程专栏
什么是高阶函数?
JavaScript中,一个函数可以接收另一个函数作为参数或将函数作为输出返回,这种函数就称之为高阶函数。
- 高阶函数可以对其他函数进行操作:
- 作为其它函数的
参数
- 作为其它函数的
返回结果
- 作为其它函数的
作为其它函数的参数使用
示例:模拟 Array.prototype.map()
Array.prototype.map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
let array = [1,2,3,4,5] // 数字组成的数组
const square = item=>item ** 2 // 回调函数,进行求2次幂运算
const newArr = array.map(square) // 使用map对数组内数据进行计算
console.log(newArr); // 打印结果: [ 1, 4, 9, 16, 25 ]
当我们调用 array.map(square)
时,参数square
是一个回调函数,回调函数作为map函数的参数,并对数据进行了2次幂处理,最终返回了一个新的数组。
我们可以模拟一下 map()
方法:
let array = [1,2,3,4,5] // 数字组成的数组
// array:原数组 fn: 回调函数
const map = (array, fn) => {
let results = []
// 遍历原数组
for (const value of array) {
results.push(fn(value)) // 对数据中的每一项先通过回调函数 fn()进行处理,之后再放到新数组 results 中
}
return results // 返回一个新数组
}
const newArr = map(array, v => v ** 2)
console.log(newArr) // 打印结果: [ 1, 4, 9, 16, 25 ]
作为其它函数的返回结果使用
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
// 一个函数返回另一个函数
function sum (arr) {
let msg = 'Hi~ wuyanfeiying'
return function () {
console.log(msg)
}
}
// 第一种调用方式
const fn = sayHi()
fn() //Hi~ wuyanfeiying
// 第二种调用方式
sayHi()()//Hi~ wuyanfeiying
在上面函数中,返回了一个函数,而且在函数中还访问了原来函数内部的成员,就可以称为闭包
。
闭包
闭包:函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包,可以在另一个作用域中调用一个函数的内部函数并访问到该函数作用域中的成员
上面的例子(作为其它函数的返回结果使用)其实就是一个闭包
,
// 求一个数的二次方
function makePower (power) {
return function (number) {
return Math.pow(number, power)
}
}
// 求平方
let power2 = makePower(2) // 此时返回的是一个函数
// 被调用时才执行
console.log(power2(4)) // 16
console.log(power2(5)) // 25
每次调用都会返回一个新的函数,即使传入相同的参数:
// 求平方
// 创建两个新函数:
let power2_1 = makePower(2)
let power2_2 = makePower(2)
power2_1 === power2_2 // false
power2_1()
和 power2_2()
的调用结果互不影响。
闭包的作用
把函数内部成员的作用范围延长
- 是一个能够读取其他函数内部变量的函数,实质上是变量的解析过程(由内而外)
函数执行的时候在执行栈上,执行完毕之后从执行栈上移除,内部成员的内存被释放。但是在函数执行完毕移除之后,释放内存的时候,如果外部有引用,则内部成员的内存不能被释放。
-
可以用来封装私有变量,实现模拟化
-
可以保存变量到内存中
使用高阶函数的意义
- 减少了代码的长度,增加了可读性并简化了可访问性。
- 高阶函数用来抽象通用的问题, 在调用的时候不需要考虑内部是如何实现的。