javascript閉包詳解

來源:互聯網
上載者:User

javascript閉包詳解

今天我們從記憶體結構上來講解下 javascript中的閉包概念。

閉包:是指有權訪問另外一個函數範圍中的變數的函數。建立閉包的常見方式就是在一個函數內部建立另外一個函數。

在javascript中沒有塊級範圍,一般為了給某個函數申明一些只有該函數才能使用的局部變數時,我們就會用到閉包,這樣我們可以很大程度上減少全域範圍中的變數,淨化全域範圍。

使用閉包有如上的好處,當然這樣的好處是需要付出代價的,代價就是記憶體的佔用。

如何理解上面的那句話呢?

每個函數的執行,都會建立一個與該函數相關的函數執行環境,或者說是函數執行內容。這個執行內容中有一個屬性 scope chain(範圍鏈指標),這個指標指向一個範圍鏈結構,範圍鏈中的指標又都指向各個範圍對應的使用中的物件。正常情況,一個函數在調用開始執行時建立這個函數執行內容及相應的範圍鏈,在函數執行結束後釋放函數執行內容及相應範圍鏈所佔的空間。

比如:

    //聲明函數    function test(){    var str = "hello world";    console.log(str);    }    //調用函數    test();

在調用函數的時候會在記憶體中產生如的結構:


但是閉包的情況就有點特殊了,由於閉包函數可以訪問外層函數中的變數,所以外層函數在執行結束後,其範圍使用中的物件並不會被釋放(注意,外層函數執 行結束後執行環境和對應的範圍鏈就會被銷毀),而是被閉包函數的範圍鏈所引用,直到閉包函數被銷毀後,外層函數的範圍使用中的物件才會被銷毀。這也正是 閉包要佔用記憶體的原因。

所以使用閉包有好處,也有壞處,濫用閉包會造成記憶體的大量消耗。

使用閉包還有其他的副作用,可以說是bug,也可以說不是,相對不同的業務可能就會有不同的看法。

這個副作用是閉包函數只能取到外層函數變數的最終值。

測試代碼如下:(這裡使用了jquery對象)

    /*閉包缺陷*/    (function($){    var result = new Array(),    i = 0;    for(;i<10;i++){    result[i] = function(){    return i;    };    }    $.RES1 = result;    })(jQuery);    // 執行數組中的函數    $.RES1[0]();

上面的代碼先通過匿名函數運算式開闢了一塊私人範圍,這個匿名函數就是我們上面所說的外層函數,該外層函數有一個參數$,同時還定義了變數result和 I , 通過for迴圈給數組result賦值一個匿名函數,這個匿名函數就是閉包,他訪問了外層函數的變數I , 理論上數組result[i]() 會返回相應的數組下標值,實際情況卻不如所願。

如上代碼 $.RES1[0]() 的執行結果是10.

為什麼會這樣呢,因為i的最終值就是10.

下面我們通過來詳細說明下,上面的那段代碼執行時在記憶體中到底發生了什麼:


那麼這個副作用有沒有辦法可以修複呢?當然可以!

我們可以通過下面的代碼來達到我們的預期。

    /*修複閉包缺陷*/    (function($){    var result = new Array(),    i = 0;    for(;i<10;i++){    result[i] = function(num){    return function(){    return num;    }    }(i);    }    $.RES2 = result;    })(jQuery);    //調用閉包函數    console.log($.RES2[0]());

上面的代碼又在記憶體中發生了什嗎?我們同樣用下面的一幅圖來詳細解釋。看懂了上面的圖,我們也就不難理解下面的圖。

閱讀原文:javascript閉包詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.