Skip to content

高阶函数

前言

高阶函数至少要满足下面条件之一的

  • 函数可以作为参数被传递
  • 函数可以作为返回值输出

回调函数

下面例子中使用回调函数给新建的每个 div 设置样式,如果全部都在一个函数里,显然是不合理的,这样可以将创建 div 和设置样式的两个逻辑进行分离

其实设置样式可能是用户发起的,所以这样就完美了进行了分离

js
function renderDiv(callback) {
  for (let i = 0; i < 10; i++) {
    const div = document.createElement('div')
    div.innerText = i
    document.body.appendChild(div)
    if (typeof callback === 'function') {
      callback(div)
    }
  }
}

renderDiv((node) => {
  node.style.color = 'red'
})

函数作为返回值输出

比如我们可以使用 Object.prototype.toString 可以进行类型是判断

见下面例子

js
function getType(type) {
  return function (target) {
    return Object.prototype.toString.call(target) === `[object ${type}]`
  }
}

const t1 = getType('String')

console.log(t1('123')) // true
console.log(t1(222)) // false

简单的单例模式

下面是一个简单的单例模式例子,单例模式将会在下一章进行详细介绍

js
function fun(callback) {
  let res
  return function () {
    return res || (res = callback())
  }
}

const getFun = fun(() => {
  return { name: '张三' }
})

const res1 = getFun()
const res2 = getFun()

console.log(res1 === res2) // true

上面是一个高阶函数的例子,既把函数作为参数传递,又在函数执行后返回了一个函数

高阶函数应用

比如我们想要计算我们一个月每天总共的开销,代码如下

js
let moneyAll = 0
function add(money) {
  moneyAll += money
}

add(19)
add(20)
add(12)

console.log(moneyAll) // 51

但是呢,我们其实并不关心每天花多少钱,所以只需要到月底直接计算一次就可以了,所以改写函数为

js
function addMoney() {
  const moneyArr = []

  return function () {
    // 代表需要求值了
    if (arguments.length === 0) {
      let money = 0
      for (let i = 0; i < moneyArr.length; i++) {
        money += moneyArr[i][0]
      }
      return money
    } else {
      // 存储值
      moneyArr.push(arguments)
    }
  }
}

const add = addMoney()

add(10)
add(20)
add(90)
add(80)

console.log(add()) // 200

但是项目的函数相对较大,所有的逻辑都放在一个函数里面了,下面进行拆分

js
function addMoney(callback) {
  const moneyArr = []
  return function () {
    if (arguments.length === 0) {
      return callback.apply(this, moneyArr)
    } else {
      moneyArr.push(arguments[0])
    }
  }
}

function cont(...moneyArr) {
  let money = 0
  return function () {
    for (let i = 0; i < moneyArr.length; i++) {
      money += moneyArr[i]
    }
    return money
  }
}

const add = addMoney(cont)

add(10)
add(20)
add(30)

const res = add()
console.log(res())