成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

簡單理解 JavaScript 閉包問題

lyning / 3572人閱讀

摘要:從我年開始接觸前端,知道閉包這個詞,已經過去兩年了。概念閉包,在高級程序設計里面是這樣介紹的閉包是指有權訪問另一個作用域中的變量的函數(shù)。這樣形成的閉包雖然可以使外部可以訪問到內部的函數(shù),但是導致了原有的作用域鏈不釋放,會造成內存泄漏。

從我16年開始接觸前端,知道閉包這個詞,已經過去兩年了。這兩年里,閉包這個概念我在很多地方了解過,卻實在沒有真的理解,久而久之,變成了一塊心病。這不,趁著現(xiàn)在項目告一段落的時間,我又開始折騰它了,在網(wǎng)易云課堂上找了些資源來看。哈哈,可能是因為已經做了些項目的緣故,這次終于能理解它到底是個什么玩意兒了。

概念

閉包,在《javascripts高級程序設計》里面是這樣介紹的:閉包是指有權訪問另一個作用域中的變量的函數(shù)。額。。這句話我以前看過很多遍,但依然不是很懂,只知道它是跟作用域有關?,F(xiàn)在我知道了,如果這句話換成:但凡是內部的函數(shù)被保存到了外部,必定生成閉包。這樣就容易理解多了不是。
我們以下面的這個代碼塊為例:

例子解釋
function a() {
    const num = 100;
    function b () {
        num++;
        console.log(num);
    }
     return b;
}
const demo = a();
demo();
demo();

我們先執(zhí)行上述代碼,看看結果是什么:

為什么是這樣呢?

a()執(zhí)行的結果是返回b,所以demo指的是b,則demo()指的是b();也就是說原先在a里面的b,在b的外部執(zhí)行;
我們已經知道了作用域和作用域鏈的概念,上面代碼的作用域是這樣的:

a執(zhí)行完,返回了b,此時的b只是聲明,但還沒調用,所以沒有形成自己的AO,但作用域鏈和 a doing 時是一樣的,所以雖然 a() 的作用域被銷毀了,但是相同的一份卻被b保存到了外面。這也就是內部函數(shù)被保存到了外面形成閉包的本質。這樣也不難理解為什么上述代碼打印出來的值是那樣的了:

執(zhí)行第一個demo()時,也即是執(zhí)行 b(),由于b保存了a的作用域鏈,所以也可以訪問到 num ,執(zhí)行 b() 后,加一;

那為什么第二次執(zhí)行 demo(),打印出的值還是有自增了呢?這是因為操作的都是保存在 b 里的 num ,雖然每次調用 demo() 都會形成新的作用域鏈,但是num,卻是每次從上一次的作用域鏈直接 copy到當前作用域鏈中的。

這樣形成的閉包雖然可以使外部可以訪問到內部的函數(shù),但是導致了原有的作用域鏈不釋放,會造成內存泄漏。(內存泄漏的意思就是占用內存,可用內存資源變少了)。所以如果不是特殊需要,應盡量防止這種情況發(fā)生。

并且,作用域鏈的配置機制引出了一個值得注意的副作用:即閉包只取得包含函數(shù)中任何變量最后一個值,比如下面這個例子:

 function createFunctions() {
     var result = [];
     for(let i = 0; i< 10; i++) {
         result[i] = function() {
             console.log(i);
          }
       }
    return result;
 }
var myArr = createFunctions();
for(var j = 0; j < 10; j++) {
       myArr[j]();
 }

這個函數(shù)會返回一個函數(shù)數(shù)組,表面上看,似乎每個函數(shù)都應該有自己的索引值,即會返回:0,1,2...9;但實際上,每個函數(shù)都會返回10;這是因為在createFunctions()執(zhí)行時,for循環(huán)跳出的條件是i=10;所以函數(shù)返回后,i的值是10 ;而每個result的作用域鏈中都保存這createFunctions()的AO,所以他們引用的都是createFunctions()的i值,所以每個函數(shù)內部i的值都是10;
這樣,我們可以創(chuàng)建一個立即執(zhí)行函數(shù)強制讓閉包的行為符合預期:

function createFunctions() {
     var result = [];
     for(var i = 0; i < 10; i++) {
           (function(j) {
             result[i] = function() {
                document.write(j + " ");
                }
          }(i));
     }
    return result;
}
var myArr = createFunctions();
for(var j = 0; j < 10; j++) {
       myArr[j]();
 }
典型應用

下面看看幾個用到閉包的典型例子:

實現(xiàn)共有變量

如累加器:調用多少次,累加多少次,用閉包更加模塊化

function add() {
            var count = 0;
            function demo() {
                count++;
                console.log(count);
            }
            return demo;
        }
        var counter = add();
        counter();//1
        counter();//2
        counter();//3

實現(xiàn)緩存

如eater: eat和push保存的都是eater的AO;,所以eat中food改變后。實際上是eater變了,所以也會影響push;

function eater() {
            var food = "";
            var obj = {
                eat: function() {
                    console.log("eating" + food);
                    food = "";
                },
                push: function(myFood) {
                    food = myFood;
                } 
            }
            return obj;// 相當于返回里面的eat和push操作food;
        }
        var eater1 = eater();
        eater1.push("banana");
        eater1.eat();

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/100262.html

相關文章

  • 理解 JavaScript 閉包

    摘要:如何在初學就理解閉包你需要接著讀下去。這樣定義閉包是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合。小結閉包在中隨處可見。閉包是中的精華部分,理解它需要具備一定的作用域執(zhí)行棧的知識。 這是本系列的第 4 篇文章。 作為 JS 初學者,第一次接觸閉包的概念是因為寫出了類似下面的代碼: for (var i = 0; i < helpText.length; i++) { var item = he...

    寵來也 評論0 收藏0
  • 簡單理解JavaScript中的閉包

    摘要:閉包在我理解是一種比較抽象的東西。所以我寫了一篇博文來方便自己理解閉包。那么現(xiàn)在我們可以解釋一下閉包的第一個定義在計算機科學中,閉包是引用了自由變量的函數(shù)。循環(huán)中創(chuàng)建閉包在我們使用的關鍵字之前,閉包的一個常見問題就出現(xiàn)在循環(huán)中創(chuàng)建閉包。 零. 前言 從我開始接觸前端時就聽說過閉包,但是一直不理解閉包究竟是什么。上網(wǎng)看了各種博客,大家對閉包的說法不一。閉包在我理解是一種比較抽象的東西。所...

    sihai 評論0 收藏0
  • JavaScript閉包簡單理解

    摘要:閉包是函數(shù)內部的子函數(shù)能讀取局部變量二閉包的特點函數(shù)里面嵌套函數(shù)內部函數(shù)能訪問外部函數(shù)的變量定義的參數(shù)和變量不會回收三閉包的前提先明白什么是全局變量和局部變量中聲明變量格式關鍵字變量名標識符。建議在退出函數(shù)之前,將不使用的局部變量全部刪除。 一、閉包的概念 閉包是指一個函數(shù)能夠訪問其函數(shù)外部作用域中的變量。JavaScript閉包是函數(shù)內部的子函數(shù)能讀取局部變量 二、閉包的特點 函數(shù)...

    hzx 評論0 收藏0
  • JavaScript閉包初探

    摘要:說了半天,究竟什么是閉包呢閉包就是函數(shù)的局部變量集合,只是這些局部變量在函數(shù)返回后會繼續(xù)存在。彈出上面函數(shù)中的函數(shù)就是閉包,就是通過建立函數(shù)來訪問函數(shù)內部的局部變量。閉包會在父函數(shù)外部,改變父函數(shù)內部變量的值。 JavaScript的閉包 首先聲明,這是一篇面向小白的博客,不過也歡迎各位大牛批評指正,謝謝。 ??其實關于閉包各個論壇社區(qū)里都有很多的文章來講它,畢竟閉包是JavaScri...

    沈建明 評論0 收藏0
  • JavaScript閉包初探

    摘要:說了半天,究竟什么是閉包呢閉包就是函數(shù)的局部變量集合,只是這些局部變量在函數(shù)返回后會繼續(xù)存在。彈出上面函數(shù)中的函數(shù)就是閉包,就是通過建立函數(shù)來訪問函數(shù)內部的局部變量。閉包會在父函數(shù)外部,改變父函數(shù)內部變量的值。 JavaScript的閉包 首先聲明,這是一篇面向小白的博客,不過也歡迎各位大牛批評指正,謝謝。 ??其實關于閉包各個論壇社區(qū)里都有很多的文章來講它,畢竟閉包是JavaScri...

    canger 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<