函數(shù)式編程基本概念

編程范式

函數(shù)式編程(Function Programming, FP)是編程范式之一(還包括面向?qū)ο缶幊?、面向過程編程)

  • 面向?qū)ο缶幊谭绞剑喊熏F(xiàn)實事物抽象成程序世界類和對象,通過封裝、繼承和多態(tài)演示事物的聯(lián)系,C++、JAVA

  • 面向過程編程方式:把事情拆分成一個個函數(shù)和數(shù)據(jù),按照一定順序,執(zhí)行這些方法

  • 函數(shù)式編程方式:把現(xiàn)實事物和事物之間聯(lián)系抽象到程序世界,對運算過程進行抽象

函數(shù)式編程
  • 程序本質(zhì):根據(jù)輸入獲取輸出

  • 數(shù)學(xué)中的函數(shù):x -> f(聯(lián)系、映射)-> y, y = f(x)

  • 函數(shù)指的是數(shù)學(xué)中的函數(shù),而不是程序中的函數(shù),如y = sin(x)

  • 相同的輸入始終得到相同的輸出(純函數(shù))

  • 函數(shù)式編程用來描述數(shù)據(jù)(函數(shù))之間的映射

  • 函數(shù)式編程語言Haskell、lisp、Scheme等

  • JS中的函數(shù)式編程

let b = 3
let sum = (a) => a + b
console.log(sum(2)) // 5

// 修改為函數(shù)式編程
let sum = (a, b) => a + b
console.log(sum(2, 3)) // 5
前置知識
函數(shù)是一等公民MDN
  • 函數(shù)可以存儲在變量中

  • 函數(shù)可以作為參數(shù)

  • 函數(shù)可以作為返回值

函數(shù)是一等公民是學(xué)習(xí)高階函數(shù)、柯里化等的基礎(chǔ)

高階函數(shù)

以函數(shù)作為輸入或者輸出的函數(shù)被稱為高階函數(shù)

  • 可以把函數(shù)作為參數(shù)傳遞給另一個函數(shù)
    // forEach
    function forEach(arr, fn) {
    for (let i of arr) {
        fn(i)
      }
    }
    
  • 可以把函數(shù)作為另一個函數(shù)的返回結(jié)果
    function makeFn () {
     let msg = 'make function'
    return function () {
     console.log(msg)
    }
    }
    const fn = makeFn()
    fn()
    // once只會執(zhí)行一次
    function once (fn) {
    let done = false
     return function () {
         if (!done) {
             done = true
           return fn.apply(this, arguments)
         }
    }
    }
    let pay = once((money) => {
    console.log(`支付,¥${money}元`)
    })
    
    pay(5)
    pay(5)
    
使用高階函數(shù)意義

高階函數(shù)就是定義抽象,屏蔽細節(jié),只需要關(guān)注目標

  • 命令式編程(注重如何做,注重過程)
    let arr = [1, 2, 3]
    for (let i =0; i < arr.length; i++) {
      console.log(arr[i])
    }
    
  • 高階函數(shù)抽象過程(注重做什么,注重結(jié)果)
    const forEach = function(arr, fn) {
      for (let i = 0; i < arr.length; i++) {
        fn(arr[i])
      }
    }
    let arr = [1, 2, 3]
    forEach(arr, (item) => {
      console.log(item)
    })
    

常用高階函數(shù)

// map
const map = (arr, fn) => {
    let resule = []
  for (let item of arr) {
    resule.push(fn(item))
    }
    return result
}
// filter
const filter = (arr, fn) => {
    let result = []
  for (let item of arr) {
    fn(item) && result.push(item)
    }
    return result
}
let arr = [1, 2, 3]
filter(arr, (item) => item > 2)
// every
const every = (arr, fn) => {
    let isTrue = true
  for (let item of arr) {
    isTrue = isTrue && fn(item)
    }
    return isTrue
}
// some
const some = (arr, fn) => {
    let isTrue = false
  for (let item of arr) {
    isTrue = fn(item)
        if (isTrue) break
    }
    return isTrue
}
let arr = [-1, 3, false]
some(arr, (item) => item > 2)
// find
const find = (arr, fn) => {
  let result = ''
    for (let item of arr) {
    if (fn(item)) {
      result = item
            break
        }
    }
    return result
}
let arr = [-1, 3, false]
let result = find(arr, (item) => item > 2)
// reduce 待完善
// sort sort((a, b) => a - b)
const sort = (arr, fn) => {
  const len = arr.length - 1
  for (let i = 0; i < len; i++) {
    let flag = true
    for (let j = 0; j < len - i; j++) {
      if (fn(arr[j], arr[j + 1])) {
        flag = false
        let temp = arr[j]
        arr[j] = arr[j + 1]
        arr[j + 1] = temp
      }
    }
    // 如果一次交換都沒有發(fā)生,說明已經(jīng)排好序了,直接返回
    if (flag) {
        return arr
    }
  }
}
let arr = [12, 4, 43, 2, 12, 45]
let r = sort(arr, (a, b) => a - b > 0)
閉包
  • 閉包:一個函數(shù)和對其周圍狀態(tài)(lexical environment,詞法環(huán)境)的引用捆綁在一起(或者說函數(shù)被引用包圍),這樣的組合就是閉包;閉包可以在一個內(nèi)層函數(shù)中訪問到其外層函數(shù)的作用域什么是閉包?

  • 特點:外部訪問函數(shù)內(nèi)部變量、避免使用全局變量、會造成內(nèi)存泄漏

    // 函數(shù)作為返回值
    function makeFn () {
        let msg = 'Hello function'
        return function () {
          console.log(msg)
        }
    }
    const fn = makeFn()
    fn()
    
  • 閉包的本質(zhì):函數(shù)執(zhí)行會放在執(zhí)行棧上,當(dāng)函數(shù)執(zhí)行完畢,會從執(zhí)行棧上移除,但是堆上的作用域成員因為被外部引用不能釋放,因此內(nèi)部函數(shù)依然可以訪問外部函數(shù)的成員

  • 閉包案例

    function makePower(power) {
      return function(num) {
        return Math.pow(num, power)
      }
    }
    let power2 = makePower(2)
    console.log(power2(4))
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容