簡單理解Javascript閉包

  理解閉包,先了解一下Javascript變量的做用域。有兩種,全局變量和局部變量。安全

  例子1:閉包

<script>
    var a = 0;
    function fun(){
        var b = 0;
        console(a+" "+b);
    }    
</script>

a是全局變量,b是局部變量。函數內部能夠直接讀取全局變量,可是在函數外部沒法讀取函數內部的局部變量。函數

  如何從外部讀取函數內部的局部變量?性能

  例子2:spa

function fun(num){
    var b = 0;
    b += num;
    return b;
}
var re_b = fun(1);
console.log(re_b);    //1
re_b = fun(2);
console.log(re_b);    //2

fun()將局部變量b做爲返回結果;code

  例子3:對象

function fun(){
    var b = 0;
    function fun2(num){
        b += num;
        return b;
    }
    return fun2
}
var re_b = fun();
console.log(re_b(1)); //1
console.log(re_b(2)); //3  

簡單分析一下例子3代碼:blog

定義普通函數fun;ip

在fun中定義變量b,普通函數fun2(參數),返回fun2;內存

在fun2中將參數num與b相加後賦予b,返回b;

執行fun,並把返回結果賦予re_b,此時re_b的類型爲function;

執行re_b(1),結果輸出1(0+1);

執行re_b(2),結果輸出3(1+2);

上述方法即爲閉包。

在瞭解閉包的做用以前,咱們先了解一下 Javascript 中的 垃圾回收 機制,在 Javascript 中,若是一個對象再也不被引用,那麼這個對象就會被 GC 回收,不然這個對象一直會保存在內存中。

例子2中,執行完fun,變量b就會被釋放回收;

例子3中,fun2定義在fun中,即fun2依賴於fun,全局變量re_b引用fun2,fun就間接被引用,即fun和fun2與re_b共存亡。只要re_b沒被釋放回收,變量b就一直在內存中。這也就是閉包的做用,fun執行完並返回後,閉包使得Javascript的垃圾回收機制GC不會收回fun所佔用的資源。

一句話說,當一個內部函數被其外部函數以外的變量引用時,就造成了一個閉包。

  閉包的應用場景:保護函數內的變量安全;在內存中維持一個變量;經過保護變量的安全實現JS私有屬性和私有方法。

  閉包的一個簡單應用:

for(var i=0;i<5;i++){
    setTimeout(function(){
        console.log(i)
    },1000*i)
}
    

結果爲,每秒鐘輸出一個5,一共輸出5次。

 

for(var i=0;i<5;i++){
    (function fun(i) {
        setTimeout(function(){
       console.log(i)
        },1000*i)
    })(i)
}

結果爲,每秒鐘輸出一個數,0,1,2,3,4。

第一個例子中每次循環中的setTimeout回調函數記住的i的值是for循環做用域中的值,此時都是5,而第二個例子記住的i的數爲setTimeout的父級做用域自執行函數中的i的值,依次爲0,1,2,3,4。

   注意點:因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,濫用閉包,會形成網頁的性能問題,在IE中可能致使內存泄露

相關文章
相關標籤/搜索