js閉包之初步理解( JavaScript closure)

    閉包一直是js中一個比較難於理解的東西,而平時用途又很是多,所以不得不對閉包進行必要的理解,如今來講說我對js閉包的理解。瀏覽器

    要理解閉包,確定是要先了解js的一個重要特性, 回想一下,那就是函數做用域,做用域分全局和局部,因爲做用域鏈的存在,全局變量能在任何地方被訪問到,相反,局部變閉包

量只能在局部訪問,而沒法在全局的做用域中被訪問。由於若是你想訪問某個局部變量,首先搜索當前做用域中的變量,若是沒有,就會繼續向上搜索,直到做用域頂端。先看一個函數

例子:spa

1 var gl = 3;
2 var foo = function(){
3     var lo=2;
4 }
5 foo();
6 
7 console.log(gl);//3
8 console.log(lo);//lo is not defined

    那麼,要怎麼在外部做用域中拿到局部做用域的變量呢?換句話說,我怎麼在全局做用域中,拿到foo中的變量lo呢?code

    例子:blog

1 function foo() {
2     var x = 2;
3     function bar() {
4         console.log(x);
5     };
6 }
7 console.log(x);//x is not defined

    我想在外部拿到x的值,該怎麼作?內存

    首先,在外部做用域中是沒法訪問到foo函數甚至bar中的變量的,來看,在bar的做用域中,是能夠訪問foo的做用域中的變量的,所以,我只要在調用foo函數時,將他內部的作用域

bar函數返回出來,結果會怎樣呢?改寫一下以上代碼:io

1 function foo() {
2     var x = 2;
3     function bar() {
4         console.log(x);
5     };
6     return bar
7 }
8 var func = foo();
9 func(); //2

    這樣就拿到了x的值,這就是最簡單的閉包。console

    再來看一個比較常見的閉包應用場景:

 

 1 function f1() {
 2     var a = 1;
 3     return function() {
 4         a++;
 5         console.log(a);
 6     }
 7 }
 8 var f2 = f1();
 9 f2();//2
10 f2();//3
11 f2();//4

    當我執行第一個f2的時候,a的值是從1變成了2,而在f1()調用時賦值給了f2,產生了一個引用,所以,a的值暫時被保存在閉包中或者是f2中,所以沒有被js的垃圾回收機制回收掉,因此,當我再一次調用f2的時候,a的值是上一次的值,也就是2,那麼這次調用a的值就變成3了,以此類推。

    這些知識很基本的閉包基礎,其實只要是在寫js腳本,無時無刻都在不經意間會用到閉包,而閉包使用不當,會形成內存泄露,除非你強制關閉瀏覽器。

相關文章
相關標籤/搜索