js高阶函数

98 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

什么是高阶函数

简单来说,如果一个函数的参数是一个函数,或者一个函数的返回值是一个函数,那么这函数就是一个高阶函数。

函数参数是一个函数

像开发中经常用到的回调函数,其就是作为参数传入某个函数中,如下

function fn(callback) {
  console.log('fn')
  ...
  callback && callback()
}

fn(() => {
  console.log('callback')
})

在js的数组Array中,也内置了很多高阶函数,例如数组的map、filter等方法,它们也是接收了一个函数作为参数来实现不同的功能。另外,我们常用的定时器方法setTimeout、setInterval方法参数中也是接收了函数,它们也是高阶函数。除此之外,还有很多常用的方法都是以接收函数参数的方式来实现其特定的功能。

函数返回值是一个函数

如果一个函数返回了一个函数,当前这个函数也是一个高阶函数

function fn() {
  ...
  return function() {
    ...
  }
}

当然,如果一个函数其参数是函数并且其返回值也是函数,那么它也是高阶函数。

函数参数和返回值均是函数

这种场景在我们实际的开发过程中也是挺常见的,例如,我们想在之前写的一段公共代码中,增加一个新的业务,这种情况下,我们就不能直接在公共代码中进行改动,因为可能有很多地方调用了这段代码,但并不是所有地方都需要添加新的业务,所以我们在扩展代码时,一定要保证不要破坏原有函数的功能。

那么这种场景中,我们就可以给这个方法添加一个方法,在它执行之前调用,如下:

function fn() {
  console.log('fn')
}

Function.prototype.before = function (callback) {
  return () => {
    callback()
    this() // 注意箭头函数中的this指调用者,这里也就是fn
  }
}

let beforeFn = fn.before(function () {
  console.log('before fn')
})

beforeFn()
// 输出:
// before fn
// fn

在上述例子中,我们在函数原型上增加一个before方法,这个方法中参数是一个函数,这里可以用来写新增的业务逻辑,然后before函数返回一个函数,这个函数中执行函数参数并调用老的函数,这样,在需要增加新业务的地方,我们就可以直接调用fn的before方法,这样即增加了新业务,也保证了以前的功能没有被破坏。

在这个例子中,before方法就是参数和返回值均是函数的高阶函数。