JS数组中的高阶函数

200 阅读2分钟

JS数组中的高阶函数

定义

一个函数可以接收另一个函数作为参数或者返回值为一个函数,这种函数就称之为高阶函数。

数组中的高阶函数

map

map方法接收一个函数,参数为[item, index],对每个数据进行迭代后返回新数组,不改变原数组。

let arr = [1,2,3,4,5]
let newArr = arr.map(item => item*2)
console.log(newArr) // [2,4,6,8,10]
console.log(arr) // [1,2,3,4,5]

filter

filter方法接收一个函数,参数为item、index,当每个数据进行迭代,返回true/false,并最终返回为true的新数组

  let arr = [1,2,3,4,5]
  console.log(arr.filter(item => item > 3)) // [4,5]
  console.log(arr) // [1,2,3,4,5]

reduce

reduce函数有两个参数,callback,initialValue,迭代函数和初始值。callback函数接收四个参数,accumator、currentItem、index、arr。 每次accumator作为迭代的返回值。当没有initialValue的时候,把数组的第一个参数作为累计的初始值,并从index为1(第二个元素)开始迭代。 详见js基础:reduce详解

let arr = [1,2,3,4,5]
let val = arr.reduce((acc, cur, index) => {
  return acc + cur
})
console.log(val) // 15

sort

sort方法接收一个函数,根据函数的执行结果对数组进行排序,返回排序后的数组。函数接收两个比较的参数a、b,当比较函数返回值大于0,则代表a的下标值比b大,即a应该排在b后面。反之,比较函数小于0,则b应该在a的后面。 sort内部实现?

let arr = [3,4,19,4,8,1,2,20]
arr.sort((a,b) => { // 
  if (a > b) return 1
  else if (a < b) return -1
  else if (a == b) return 0
})

其他高级函数应用

执行一次

once 函数只能执行一次,执行一次后把fn设置为null

function once(fn) {
  return function (...args) {
    if (fn) {
      flag = true
      let ret = fn.apply(this, args)
      fn = null // 执行完一次后把fn设置为null
      return ret
    }
  }
}

执行多少次后不能再执行 before

function before(n, func) {
  let result
  if (typeof func !== 'function') {
    throw ''
  }
  return function (...args) {
    if (--n > 0) {
      result = func.apply(this, args)
    }
    if (n <= 1) {
      func = undefined
    }
    return result
  }
}

通过添加可点击次数后,我们只能点击一次的就可以直接调用before了。

function once(func) {
  return before(2, func)
}

中间件

koa中中间件的实现就是一个高阶函数。

// 简单中间件使用
app.use(async (ctx, next) => { 
  next()
})
// 中间件实现 想不出实现的具体
// 中间件的应用
function compose(middleware) {
 return function(context, next) {
   let index = -1
   return dispatch(0)

   function dispatch(i) {
     if (i <= index) return Promise.reject(new Error('error'))
     index = i
     fn = middleware[i]
     if (i === midelware.length) fn = next() // 最后一个调用next
     if (!fn) return Promise.resolve()
     try {// 核心方法
       return Promise.resolve(fn(context, dispatch.bind(null, i + 1)))
     } catch(err) {
       return Promise.reject(err)
     }
   }
 }
 
}