溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS5高階函數(shù)有哪些

發(fā)布時間:2021-12-01 15:07:06 來源:億速云 閱讀:107 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“JS5高階函數(shù)有哪些”,在日常操作中,相信很多人在JS5高階函數(shù)有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JS5高階函數(shù)有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    1、前言

    在JavaScript中,函數(shù)實際上也是一個數(shù)據(jù),也就是說函數(shù)也可以賦值給一個變量。

    2、遞歸

    所謂的遞歸,就是指函數(shù)自己調(diào)用自己;用一個故事來說呢就是:從前有座山,山里有座廟,廟里有個老和尚,正在給小和尚講故事呢!故事是什么呢?“從前有座山,山里有座廟,廟里有個老和尚,正在給小和尚講故事呢!故事是什么呢?‘從前有座山,山里有座廟,廟里有個老和尚,正在給小和尚講故事呢!故事是什么呢?……'” 。

    從某種意義上說,遞歸近似于循環(huán)。兩者都重復執(zhí)行相同的代碼,并且兩者都需要一個終止條件,以避免無限循環(huán)或者無限遞歸。

    遞歸所需要的必要條件如下:

    • 子問題跟原始問題一樣,且更為簡單

    • 必須有個出口

    在JavaScript中想要遞歸調(diào)用存在兩種方式

    • 通過使用函數(shù)名實現(xiàn)

    • 通過使用arguments.callee屬性實現(xiàn)。

    如下代碼展示了簡單的遞歸:

    var v = 1 // 出口條件
    function fun() {
      console.log('第' + v + '次調(diào)用函數(shù)')
      v++
      if (v <= 3) {
        fun()
      }
    }
    fun()

    執(zhí)行結果如下

    第1次調(diào)用函數(shù)
    第2次調(diào)用函數(shù)
    第3次調(diào)用函數(shù)

    3、回調(diào)函數(shù)

    然函數(shù)與任何可以被賦值給變量的數(shù)據(jù)是相同的,那么它當然可以像其他數(shù)據(jù)那樣被定義、刪除、拷貝,以及當成參數(shù)傳遞給其他函數(shù)。

    當一個函數(shù)作為參數(shù)傳遞給另一個函數(shù)時,作為參數(shù)的函數(shù)被稱之為回調(diào)函數(shù)。作為使用回調(diào)函數(shù)的函數(shù)稱為目標函數(shù)(外層函數(shù))

    示例代碼如下所示:

    // 定義一個函數(shù),這個函數(shù)有兩個函數(shù)類型的參數(shù),然后分別執(zhí)行那兩個函數(shù),并返回它們的和。
    function sum(a, b) {
      // 目標函數(shù)
      return a() + b()
    }
    
    function one() {
      // 回調(diào)函數(shù)
      return 1
    }
    
    function two() {
      // 回調(diào)函數(shù)
      return 2
    }
    
    console.log(sum(one, two)) // 3

    代碼執(zhí)行流程如下:

    當執(zhí)行sum函數(shù)時,傳入兩個實參,在sum函數(shù)中,會將兩個實參作為函數(shù)執(zhí)行,并將返回值計算并返回。

    3.1匿名回調(diào)函數(shù)

    所謂匿名回調(diào)函數(shù),就是目標函數(shù)中的參數(shù)是沒有名稱的函數(shù),將上一段代碼修改為使用匿名回調(diào)函數(shù)

    // 定義一個函數(shù),這個函數(shù)有兩個函數(shù)類型的參數(shù),然后分別執(zhí)行那兩個函數(shù),并返回它們的和。
    function sum(a, b) {
      // 目標函數(shù)
      return a() + b()
    }
    
    console.log(
      sum(
        function () {
          // 匿名回調(diào)函數(shù)
          return 1
        },
        function () {
          //  匿名回調(diào)函數(shù)
          return 2
        },
      ),
    ) // 3

    3.2帶參數(shù)的回調(diào)函數(shù)

    回調(diào)函數(shù)是可以增加參數(shù)的,示例代碼如下:

    function multiplyByTwo(list, callback) {
      list.forEach(function (v, i) {
        callback(v * 2, i)
      })
    }
    var list = [1, 2, 3]
    multiplyByTwo(list, function (v, i) {
      list[i] = v
    })
    console.log(list) // [ 2, 4, 6 ]

    3.3回調(diào)函數(shù)的優(yōu)缺點

    • 匿名回調(diào)函數(shù)節(jié)省了全局命名空間

    • 將私有的數(shù)據(jù)內(nèi)容開放給指定位置使用

    • 保證封裝性——雖然可以使用私有數(shù)據(jù),但是并不知道來源

    • 有助于提升性能

    但是回調(diào)函數(shù)也是有缺點的,當目標函數(shù)的參數(shù)是一個回調(diào)函數(shù)時,回調(diào)函數(shù)的參數(shù)又是另一個回調(diào)函數(shù),另一個回調(diào)函數(shù)的參數(shù)還是一個回調(diào)函數(shù)…也就是套娃,也就形成了回調(diào)陷阱,嚴重一點可以說回調(diào)地獄。

    4、自調(diào)函數(shù)

    所謂的自調(diào)函數(shù),就是定義后立即調(diào)用的函數(shù),示例代碼如下所示:

    ;(function () {
      console.log('自調(diào)函數(shù)')
    })()

    這種語法看上去有點唬人,其實沒有什么,我們只需將匿名函數(shù)的定義放進一對括號中,然后外面再緊跟一對括號即可。

    語法結構如下圖所示:

    JS5高階函數(shù)有哪些

    自調(diào)函數(shù)除了以上兩種方式外,還有以下幾種不常用的方式,示例代碼如下:

    ;+(function (v) {
      // 形參
      var w = 100 // 局部變量
      console.log('自調(diào)函數(shù)' + v)
    })(1) // 實參
    
    !(function (v) {
      var w = 100 // 局部變量
      console.log('自調(diào)函數(shù)' + v)
    })(2)
    
    ~(function (v) {
      var w = 100 // 局部變量
      console.log('自調(diào)函數(shù)' + v)
    })(3)

    使用自調(diào)匿名函數(shù)的好處是不會產(chǎn)生任何全局變量。

    缺點在于這樣的函數(shù)是無法重復執(zhí)行的(除非將它放在某個循環(huán)或其他函數(shù)中)。這也使得即時函數(shù)非常適合于執(zhí)行一些一次性的或初始化的任務。

    5、為值的函數(shù)

    將一個函數(shù)作為另一個函數(shù)的結果并返回,作為結果返回的函數(shù)稱之為作為值的函數(shù)。

    示例代碼如下:

    function outer() {
      var v = 100
      // 在函數(shù)的函數(shù)體中定義另一個函數(shù) -> 內(nèi)部(私有)函數(shù)
      return function () {
        // 使用匿名函數(shù)
        return v * 2
      }
    }
    var result = outer()
    console.log(result) // [Function]

    這樣做的好處是:

    • 有助于我們確保全局名字空間的純凈性(這意味著命名沖突的機會很?。?。

    • 確保私有性 — 這使我們可以選擇只將一些必要的函數(shù)暴露給“外部世界”,而保留屬于自己的函數(shù),使它們不為該應用程序的其他部分所用。

    6、閉包

    閉包是在函數(shù)中提出的概念,簡單來說就是一個函數(shù)定義中引用了函數(shù)外定義的變量,并且該函數(shù)可以在其定義環(huán)境外被執(zhí)行。當內(nèi)部函數(shù)以某一種方式被任何一個外部函數(shù)作用域訪問時,一個閉包就產(chǎn)生了。

    實際上閉包可以看做一種更加廣義的函數(shù)概念。因為其已經(jīng)不再是傳統(tǒng)意義上定義的函數(shù)。

    閉包的條件:

    • 外部函數(shù)中定義了內(nèi)部函數(shù)。

    • 外部函數(shù)是具有返回值,且返回值為內(nèi)部函數(shù)。

    • 內(nèi)部函數(shù)還引用了外部函數(shù)的變量。

    閉包的缺點:

    • 作用域沒有那么直觀。

    • 因為變量不會被垃圾回收所以有一定的內(nèi)存占用問題。

    閉包的作用:

    • 可以使用同級的作用域。

    • 讀取其他元素的內(nèi)部變量。

    • 延長作用域。

    • 避免污染全局變量

    閉包的原理:

    我們可以將函數(shù)的執(zhí)行分成兩個階段,即預編譯階段和執(zhí)行階段;

    • 在預編譯階段,如果發(fā)現(xiàn)內(nèi)部函數(shù)使用了外部函數(shù)的變量,它就會在內(nèi)存中 創(chuàng)建一個閉包對象并保存相對應的值,如果已經(jīng)存在閉包,則只需要增加對應屬性值即可。

    • 在執(zhí)行完成后,函數(shù)執(zhí)行上下文會被校徽,函數(shù)對閉包對象的引用也會被銷毀,但其內(nèi)部函數(shù)還持有該閉包的引用,所以內(nèi)部函數(shù)還可以繼續(xù)使用外部函數(shù)的變量

    閉包主要是利用作用域鏈的特性,一個函數(shù)內(nèi)部定義的函數(shù)會將包含該函數(shù)的活動對象添加到自己本身的作用域鏈中,函數(shù)執(zhí)行完畢,其執(zhí)行作用域鏈銷毀,但因內(nèi)部函數(shù)的作用域鏈仍然引用這個活動對象,所以其活動對象不會被銷毀,直到內(nèi)部函數(shù)被銷毀后這些活動對象才會被銷毀。

    閉包的實現(xiàn)的demo:

    // 1. 通過返回的內(nèi)部函數(shù)來操作函數(shù)中的局部變量
    function fun () {
        var v = 100; // 局部變量
        // 通過返回一個對象的方式訪問局部變量v 來完成閉包
        return {
            set: function (x) {
                v = x;
            },
            get: function () {
                return v
            }
        }
    }
    var result = fun();
    result.set(200)
    console.log(result.get()); // 200
    // 2. 定義一個局部變量,計算該函數(shù)一共調(diào)用幾次
    var generate_count = function () {
        var container = 0;
        return function () {
            container++
            console.log(`這是第${container}次調(diào)用`);
        }
    }
    
    var result = generate_count();
    result(); // 這是第1次調(diào)用
    result(); // 這是第2次調(diào)用
    result(); // 這是第3次調(diào)用
    // 3.修改 Math.pow() 函數(shù),讓求一個數(shù)的平方或者立方時,不需要每次傳遞第二個參數(shù)
    
    /*
    Math.pow(4, 2) // 求4的平方
    Math.pow(4, 3) // 求4的立方
    */
    
    // 寫一個函數(shù)生成器
    function makePower (power) {
        return (number) => {
            return Math.pow(number, power)
        }
    }
    // 平方
    let power2 = makePower(2)
    // 立方
    let power3 = makePower(3)
    // 求4的平方
    console.log(power2(4)) // 16
    // 求4的立方
    console.log(power3(4)) // 62

    到此,關于“JS5高階函數(shù)有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    js
    AI