函数式编程 以及高阶函数

231 阅读2分钟

函数式编程的概念

函数式编程是什么?

函数式编程的函数值得不是程序中的函数或者方法,而是数学组的函数映射关系

一句话来描写函数式编程

函数式编程是用来描述数据之间的映射

纯函数的概念

相同的输入始终要得到相同的输出(纯函数的概念)

通过案例了解一下:

// 非函数式
let num1 = 2
let num2 = 3
let sum = num1 + num2
console.log(sum)
// 函数式
function add (n1, n2) {
    return n1 + n2
}
let sum = add(2, 3)
console.log(sum)

高阶函数

什么是高阶函数

高阶函数全称 (Higher-order function)

1、可以把函数作为参数传递给另一个函数

2、可以把函数作为另一个函数的返回结果

通过案例了解一下

把arr的数据打印出来

function forEach (Array, fn) {
    for (let i = 0; i < Array.length; i++) {
      fn(Array[i])
    }
  }
  const arr = [1, 2, 3, 4, 5]
  
  forEach(arr, function (item) {
    console.log(item)
  })

模拟filter 判断是否是奇偶数


// 第一个参数是数组,第二个参数是满足什么条件
function filter (array, fn) {
    const react = []
    for (let i = 0; i < array.length; i++) {
        // 判断条件是否成立
      if (fn(array[i])) {
        react.push(array[i])
      }
    }
    return react
  }
  const arr = [1, 2, 3, 4, 5]
  const r = filter(arr, function (item) {
    return item % 2 === 0 // 判断是否是偶数
  })
  console.log(r)

把arr的数据打印出来(箭头函数写法)

const map = (array, fn) => {
    const results = []
    for (const value of array) {
      results.push(fn(value))
    }
    return results
  }
  // 测试方法
  let arr = [1, 2, 3, 4]
  arr = map(arr, v => v * 2)
  console.log(arr)

使用高阶函数 模拟every


// every是检测数组的数据都满足条件 如果都满足就返回true 如果有一个不满足就返回falsh
// 使用高阶函数 模拟every fn是检测数组的每一项 判断arr的是否满足 如果有一个不满足就返回falsh
const every = (array, fn) => {
    let result = true
    for (let value of array) {
      result = fn(value)
      if (!result) {
        break
      }
    }
    return result
  }
  // 测试方法
  let arr = [11, 12, 14]
  let r = every(arr, v => v > 10)
  console.log(r)

使用高阶函数 模拟some 判断奇偶数


// some 检测数组是否有一个满足指定的条件
// 使用高阶函数 模拟some 判断奇偶数
const some = (array, fn) => {
    let result = true
    for (let value of array) {
      result = fn(value)
      if (result) {
        break
      }
    }
    return result
  }
  
  const arr = [1, 3, 5, 9]
  const r = some(arr, v => v % 2 === 0)
  console.log(r)

高阶函数作为返回值


function makeFn () {
    const msg = 'hollo word'
    return function () {
      console.log(msg)
    }
  }
  const fn = makeFn()
  fn() // 第一种调用方法
  // once()() //第二种调用方法

下面我们模拟一个支付的一个过程 因为支付只能一次,要么成功要么失败

// 只执行一次
function once (fn) {
    let done = false
    return function () {
      if (!done) {
        done = true
        //  apply 改变this指向
        return fn.apply(this, arguments)
      }
    }
  }
  const pay = once(function (money) {
    console.log(`支付${money} RMB`)
  })
  
  pay(5) // 支付金额
  pay(5) // 支付金额
  pay(5) // 支付金额
  pay(5) // 支付金额
  pay(5) // 支付金额
  pay(5) // 支付金额