js學習筆記之範圍鏈和閉包

來源:互聯網
上載者:User

標籤:learn   define   相交   它的   color   執行   記憶體   text   刪除   

 在學習閉包之前我們很有必要先瞭解什麼是範圍鏈

一、範圍鏈

範圍鏈是保證對執行環境有權訪問的所有變數和函數的有序訪問。

這句話其實還是蠻抽象的,但是通過下面一個例子,我們就能清楚的瞭解到範圍鏈了。

 1 var color="blue"; 2     function changeColor(){ 3         var anotherColor="red"; 4         function swapColors(){ 5             var tempColor=anotherColor; 6             anotherColor=color; 7             color=tempColor; 8             //這裡面可以訪問color、anotherColor和tempColor 9         }10         //這裡面可以訪問anotherColor和color11     }12     //這裡面只能訪問color

以上代碼涉及了3個執行環境:全域環境、changeColor()局部環境和swapColor()局部環境。在一個變數環境中只能訪問他自己的環境和父執行環境。swapColor()的父執行環境就是changeColor(),而changeColor()的父執行環境就是全域環境。如果還不清楚可以參考

      

在f2()函數的局部環境中能訪問自己和比它等級高的,也就是a,b,c,同理f1()函數環境訪問b,a,全域環境只能訪問c。

我們這時候會發現函數外部是無法訪問內部的局部環境的,但是我們想突破範圍鏈怎麼辦呢?這時候就有了閉套件共用範圍。閉包這個名詞就出現了。

二、閉包

閉包在紅寶書中的解釋就是:有權訪問另一個函數範圍中的變數的函數。

下來舉一個簡單的例子

1  function f1(){2         var a=1;3         return function(){4             return a;5         }6     }7     alert(a);  /*結果為 a is undefined*/8     var task=f1(); /*task就是閉包,有權訪問其他函數範圍變數*/9     alert(task());/*結果為1*/

下來我們再舉一個閉包的例子

 1 function f1(){   2       var n=0; 3       task=function(){  //匿名函數 4           n+=1; 5       } 6       //這部分為閉包 7       function f2(){     8           alert(n); 9       }10       return f2 //返回       12   }13     var text=f1(); 14     alert(text()); 15     task();16     alert(text()); //結果依次為 0,undefined,1,undefined

text是f2閉包函數,實際上f2()被賦予一個全域變數,f2()始終在記憶體中,f1()是它的父級函數,所以f1()也始終在記憶體中,不會被銷毀。執行一次task()後,值變為2。至於為什麼會出現undefined是因為,undefined是text的傳回值,也就是閉包函數無傳回值了。

有時候我們想改變其他函數範圍裡的變數,這時候就可以用閉包去解決。設定兩個額外的函數去訪問內建函式。

 1 var setvalue,getvalue; 2 (function(){ 3     var n=0; 4     getvalue=function(){ 5         return n 6     } 7     setvalue=function(x){ 8         n=x; 9     }10 })(); //直接調用11 alert(getvalue()); //結果為012 setvalue(456);13 alert(getvalue());/*結果為456*/

這時候我們發現在外部就可以去改變內部變數值。

下來再舉一個利用閉包迴圈遍曆得到數組的值。有兩個程式,可以對比一下兩個程式的區別

例1:

 1 function f1(){ 2     var a=[]; 3     var i=0; 4     for(i=0;i<3;i++){ 5         a[i]=function(){ 6             return i; 7         } 8     } 9     return a;10 }11   var text=f1();12     alert(text[0]()); 13     alert(text[1]());14     alert(text[2]()); //結果都為3

因為閉包都指向局部變數i,只是給出了指標連結,對變數的引用,並沒有對值作出改變。所以結果都為3

例2:

 1  function f1(){ 2        function f2(x){  //閉包 3            return function(){ 4                return x; 5            } 6        } 7        var a=[]; 8        var i=0; 9        for(i=0;i<3;i++){10            a[i]=f2(i);11        }12        return a;13    }14     var text=f1();15     alert(text[0]()); //結果為116     alert(text[1]());//結果為217     alert(text[2]());//結果為3

利用一個函數參數,用閉包去擷取內部變數的值。

程式是這樣走的:先判斷誰進來--》調用閉包--》閉包返回內建函式參數--》最後再建立數組。

三、閉包的缺點

  這上面幾個例子確實體會到了閉包的強大,但是閉包也有明顯的缺點,它使函數中的變數都儲存在記憶體中,佔用記憶體,導致頁面載入緩慢。所以再退出函數前,將不用的局部變數刪除。

四、總結

  以上就是我學習閉包總結的一點小知識。大家互相交流哈 O(∩_∩)O。

  附阮一峰老師對閉包的理解:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html?20120612141317#comments 

  

 

 

 

 

 

 

js學習筆記之範圍鏈和閉包

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.