最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript高級之閉包詳解

 更新時間:2021年12月17日 16:00:55   作者:hangshao_123  
這篇文章主要為大家介紹了JavaScript閉包,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

1. 閉包的概念

來看一般函數(shù)的執(zhí)行和啟發(fā):

        function stop() {
            var num = 0;
            console.log(num);
        }
        stop(); // 打印出來num是0
        console.log(num); // 報錯 函數(shù)未定義

1. 此時,函數(shù)的外部無法訪問函數(shù)內部的變量

2.?函數(shù)內部定義的變量不會一直存在,隨著函數(shù)的運行結束而消失

閉包的概念:

1. 是一個函數(shù),這個函數(shù)有權訪問另一個作用域中的變量。

2. 另一種說法,當內部函數(shù)的生命周期大于外部函數(shù)的聲明周期,而內部函數(shù)以某一種方式被外部作用域訪問時,閉包就產生了。

來看如下閉包的代碼和解釋:

        function fn() {
            var num = 10;
            // function fun() {
            //     console.log(num);
 
            // }
            // return fun;
            return function () {
                console.log(num); // 10
            }
        }
        var f = fn();
        f();

我們可以拆解為幾個部分:

1. fn函數(shù)里面有內部的返回值且就是一個函數(shù)。

2. return的這個函數(shù)內部打印了num變量。為什么能夠打印num變量,原因在于作用域鏈的訪問機制,下面會補充作用域和作用域鏈的知識點。

3. 我們在外部用f變量接受了fn(),也就是接受了fn的返回值【內部函數(shù)】

4. 緊接著調用f,也就是調用了fn里面的內部函數(shù)。最終能夠打印10

知識點的補充:

1.?作用域:

變量在某個范圍內起作用,超出了這個范圍,就不起作用。這個范圍就是作用域。作用域在函數(shù)的定義時就產生,而不是函數(shù)調用時產生的。

2.?作用域鏈:

一句話概括:根據(jù)【內部函數(shù)可以訪問外部函數(shù)變量】,采用就近原則一層一層向上查找變量,這個機制就叫作作用域鏈。

函數(shù)A包含了函數(shù)B,那么函數(shù)B就是函數(shù)A的內部函數(shù),

而內部函數(shù)如果要使用一個變量,首先看自己內部有沒有這個變量,

如果沒有,就會去緊挨著的上一級查找,【就近原則】

如果函數(shù)一層一層都找不到,最后才會去全局變量下面找。

        var a = 1;
        var b = 11;
        function fn1() {
            var a = 2;
            var b = '22';
            fn2();
            function fn2() {
                var a = 3;
                fn3();
                function fn3() {
                    var a = 4;
                    console.log(a); // 4
                    console.log(b); // '22'
                }
            }
        }
        fn1();

3.?垃圾回收機制

可以參考這位大哥對于JS垃圾回收機制的描述:

//m.fzitv.net/article/229425.htm

我們結合這三個概念看閉包的作用

2. 閉包的作用:

我們把函數(shù)A叫作外層的函數(shù),這個函數(shù)內部有一個函數(shù)B。

外部用一個變量f接受函數(shù)A的返回值【函數(shù)B】

而函數(shù)A作用域的變量叫作num

1. 能夠在函數(shù)的外部訪問函數(shù)內部的變量【搭建外部訪問內部作用域的通道】

原理:上面其實有解釋過。

第一要理解,作用鏈的原理看上面。函數(shù)B能夠調用函數(shù)A的變量num

第二要理解,首先函數(shù)A的返回值是函數(shù)B【內部函數(shù)】,其次這個返回值要在函數(shù)外部用變量f接受,接受以后就能夠調用函數(shù)B,函數(shù)B就會訪問函數(shù)A的變量num。而這個內部函數(shù)B就是閉包函數(shù)啦。

2. 能夠延長函數(shù)內部變量的生命周期。

第一個作用帶來第二個作用。js的變量存在垃圾回收機制,如果函數(shù)執(zhí)行完畢,變量會被清除,內存也會消除??墒侨绻瞄]包,變量可以不被立即清除。

原因是,外部的變量f接受了一個函數(shù)A的內部函數(shù)B,而這個內部函數(shù)訪問了函數(shù)A作用域的變量num,只要函數(shù)B執(zhí)行且變量f一直存在,那么變量num就會一直存在。不會因為函數(shù)A的執(zhí)行結束就消失。

參考了下面的文章,講的非常詳細,推薦看。

JavaScript閉包詳解

3. 閉包示例

后面會補充閉包的一些應用。

我們要想起什么場合用閉包,閉包不能濫用。

3.1 點擊li,輸出當前l(fā)i的索引號

    <ul class="nav">
        <li>榴蓮</li>
        <li>臭豆腐</li>
        <li>鯡魚罐頭</li>
        <li>大豬蹄子</li>
    </ul>
    <script>
        // 閉包應用-點擊li輸出當前l(fā)i的索引號
        // 1. 我們可以利用動態(tài)添加屬性的方式
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].onclick = function () {
                console.log(i); // 四個4
            }
        }
    </script>

原理:上圖這樣寫,打印出來的i永遠都是4。原因是,此時首先是非嚴格模式,在非嚴格模式下,for循環(huán)是同步執(zhí)行任務,而按鈕點擊再執(zhí)行是異步任務,同步執(zhí)行完畢,i加到了4.再執(zhí)行異步任務打印i,都是4。

改法1:用閉包

1.for循環(huán)生成四個立即執(zhí)行函數(shù)

2. 立即執(zhí)行函數(shù)是閉包的一種應用。立即執(zhí)行函數(shù)里面的所有函數(shù)包括【點擊 回調】函數(shù)都可以使用立即執(zhí)行函數(shù)的傳遞的形參。

        for (var i = 0; i < lis.length; i++) {
            (function (i) {
                // console.log(i);
                lis[i].onclick = function () {
                    console.log(i);
 
                }
            })(i);
        }

改法2:var--->let

點擊對應小li,打印i是對應索引號。使用let是ES6語法,此時for有塊級作用域

        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (let i = 0; i < lis.length; i++) {
            lis[i].onclick = function () {
                // console.log(i);
                console.log(i);
            }
        }

改法3:用設置自定義屬性index的方法

        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) { // 注意這里是var不是let
            lis[i].index = i; // 注意這里是lis[i]不是this.index,此時沒有點擊,哪里來的this
            lis[i].onclick = function () {
                console.log(this.index);
            }
        }

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!

相關文章

  • 詳解網(wǎng)站中圖片日常使用以及優(yōu)化手法

    詳解網(wǎng)站中圖片日常使用以及優(yōu)化手法

    一直都覺得網(wǎng)站優(yōu)化的重點是圖片,圖片的使用也是博大精深。本文將總結一下圖片的日常使用以及優(yōu)化手法,下面跟著小編一起來看下吧
    2017-01-01
  • await?Streaking解決原理示例詳解

    await?Streaking解決原理示例詳解

    這篇文章主要為大家介紹了await?Streaking解決原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Javascript幻燈片播放功能實現(xiàn)過程解析

    Javascript幻燈片播放功能實現(xiàn)過程解析

    這篇文章主要介紹了Javascript幻燈片播放功能實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • js中document.getElementById(id)的具體用法

    js中document.getElementById(id)的具體用法

    本文主要介紹了js中document.getElementById(id)的具體用法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 詳解JS中如何終止foreach循環(huán)

    詳解JS中如何終止foreach循環(huán)

    forEach專門用來循環(huán)數(shù)組,可以直接取到元素,同時也可以取到index值,終止forEach存在局限性,不能continue跳過或者break終止循環(huán),所以本文給大家詳細介紹了在JS中如何終止foreach循環(huán),需要的朋友可以參考下
    2024-01-01
  • JavaScript中使用document.write向頁面輸出內容實例

    JavaScript中使用document.write向頁面輸出內容實例

    這篇文章主要介紹了JavaScript中使用document.write向頁面輸出內容實例,本文講解了輸出普通文字、帶HTML標簽內容的方法,需要的朋友可以參考下
    2014-10-10
  • 前端iconfont兩種使用方式舉例詳解

    前端iconfont兩種使用方式舉例詳解

    這篇文章主要介紹了一種流行的網(wǎng)頁圖標解決方案Iconfont的相關資料,包括創(chuàng)建項目、添加圖標、下載代碼、在項目中使用Iconfont和自定義圖標樣式等步驟,需要的朋友可以參考下
    2025-01-01
  • js實現(xiàn)鼠標移入圖片放大效果

    js實現(xiàn)鼠標移入圖片放大效果

    這篇文章主要為大家詳細介紹了js實現(xiàn)鼠標移入圖片放大效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • JS實現(xiàn)的RC4加密算法示例

    JS實現(xiàn)的RC4加密算法示例

    這篇文章主要介紹了JS實現(xiàn)的RC4加密算法,結合實例形式分析基于javascript實現(xiàn)的RC4加密算法簡單定義與使用方法,需要的朋友可以參考下
    2018-08-08
  • javascript實現(xiàn)禁止復制網(wǎng)頁內容

    javascript實現(xiàn)禁止復制網(wǎng)頁內容

    這篇文章主要介紹了javascript實現(xiàn)禁止復制網(wǎng)頁內容,需要的朋友可以參考下
    2014-12-12

最新評論

松桃| 东港市| 滁州市| 青海省| 保康县| 四平市| 南丹县| 吉木萨尔县| 开封市| 万荣县| 丰都县| 新龙县| 壤塘县| 淳化县| 龙泉市| 东光县| 巩留县| 青州市| 镇远县| 苍山县| 石河子市| 民乐县| 苏尼特左旗| 张北县| 博罗县| 萨嘎县| 抚顺市| 大埔县| 滨州市| 牟定县| 龙门县| 阳谷县| 温宿县| 临安市| 襄樊市| 汽车| 响水县| 星座| 明溪县| 武安市| 定南县|