首先我们来看一下维基百科对于高阶函数的定义:
在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
- 接受一个或多个函数作为输入
- 输出一个函数
简单点来说,我们定义一个函数时,参数是函数或者返回值是函数,这个函数高阶函数。而对于JavaScript来说这两种情况都满足。
函数作为参数
function callbackFn() {
console.log('高阶函数')
}
function fnParam(fn) {
console.log('普通函数')
// fn 函数作为参数传递
fn()
}
// 测试
fnParam(callbackFn)
复制代码
上述例子fn函数作为参数传递,这种函数被称作为回调函数
回调函数是异步的基石,上述例子中 callbackFn 作为参数传递到 fnParam 函数中,callbackFn 的执行
权由fnParam 决定。
在JavaScript语言中内置的很多这种函数作为参数的高阶函数,例如
- Array.prototype.map
- Array.prototype.filter
- Array.prototype.find
- ….
以 Array.prototype.map 为例子进行详细讲解
使用高阶函数
// map 使用实例
const arr = [1, 2, 3, 4]
const result = arr.map(item => item * 2)
console.log(arr) // [1, 2, 3, 4]
console.log(result) // // [2, 4, 6, 8]
复制代码
不使用高阶函数
// 同步代码实现 map 功能
const arr = [1, 2, 3, 4]
const result = []
for(let i = 0; i < arr.length; i++) {
const item = arr[i]
result.push(item * 2)
}
console.log(arr) // [1, 2, 3, 4]
console.log(result) // // [2, 4, 6, 8]
复制代码
模拟实现
// 模拟 map
const map = (arr,fn)=>{
let res = [];
for(let i = 0; i < arr.length; i++){
res.push(fn(i))
}
return res;
}
// 测试
const newAry = map([1,23,4,5,6],item=>item**2)
console.log(newAry) // [1, 529, 16, 25, 36]
复制代码
// 模拟 filter
function filter(arr,fn){
let res = [];
for(let i = 0; i < arr.length; i++){
if(fn(arr[i])){
res.push(arr[i])
}
}
return res
}
// 测试
const ary = filter([1,2,34,5,6],function(item){
return item%2 === 0;
})
console.log(ary) // [2, 34, 6]
复制代码
函数作为返回值
我们来看一个简单例子
function getMsg() {
const msg = 'hello msg'
// 函数作为返回值
return function() {
console.log('msg')
}
}
// 测试
const firstAction = getMsg()
firstAction() // hello msg
复制代码
getMsg执行之后得到的是一个函数,这个函数赋值给了firstAction,这个firstAction就是函数作为返回值。这里会产生闭包
接下来我们利用高阶函数这两个特性来实现一个只能调用一次的函数
function once(fn) {
let done = false
return function() {
if(!done) {
done = true
return fn.apply(this, arguments)
}
}
}
const pay = once(function(money) {
console.log('支付了'+ money)
})
pay(5)
pay(5)
pay(5)
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END