閉包與變量

閉包所保存的變量是整個變量對象,而不是某個特殊的變量,即閉包只能取得包含函數中任何變量的最後一個值。

   function createFunctions(){

       var result =new Array();

       for(i=0;i<=10;i++){

           result[i]=function(){

               return i;

                   };

       }

       return result;

   }

   這個函數會返回一個函數組。表面上看,似乎每個函數都應該返自己的索引值,即位置爲0的函數返回值0,位置1的函數值返回1。但實際上,每個函數都返回10,因爲每個函數的作用域鏈中都保存着createFuctions()函數的活動對象,所以他們引用的都是同一個變量i。當i createFuctions()函數返回後,變量i 的值是10。此時每個函數都引用着保存變量i的同一個變量對象,所以在每一個函數內部i的值都是10。再看下例

   function createFunctions(){

   var result =new Array();

   for(i=0;i<=10;i++){

   result[i]=function(num){

       return function(){

           return num;

           }

       }(i);

   }

   return result;

   }

   在重寫前面的函數的createFunctions()函數後,每個函數就會返回各自不同的索引值了,在這個版本中,我們沒有直接把閉包賦值給數組,而是定義了一個匿名函數,並將立即執行該匿名函數的結果賦值給數組。這裏的匿名函數有一個參數num,也就是最終函數要返回的值。在調用每個匿名函數時,我們傳入了一個變量i。由於函數參數是按值傳遞的,所以就會將變量i的當前值複製給參數num。而在這個匿名函數內部,又創建並返回了一個訪問num的閉包。這樣一來,result數組中的每個函數都有一個自己的num變量副本,因此就可以返回各自不同的值了。

   使用閉包可以在js中模仿塊級作用域,創建並立即調用一個函數,這樣既可以執行其中的代碼,又不會再內存留下該函數的引用。閉包還可以用於在對象中創建私有變量,js中沒有私有對象屬性的概念,但可以使用閉包來實現公有方法,而通過公有方法可以訪問包含在作用域中定義的變量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章