閉包:有權訪問另一個函數作用域中的變量的函數
閉包只能取得包含函數中任何變量的最后一個值。閉包保存的是整個變量對象,而不是某個特殊的變量,下面這個例子可以清楚的說明這個問題。
function createFunctions(){ var result = new Array(); for(var i=0; i<10;i++){ result[i]=function(){ return i; }; } return result; }這個函數會返回一個函數數組,從表面看每個函數都應該返回自己的索引值,即位置0的函數返回0,位置1的函數返回1,但實際上,每個函數都返回10。因為每個函數的作用域鏈中都保存著createFunctions()函數的活動對象,所以它們的引用的都是同一個變量i。當createFunctions()函數返回后,變量i的值是10,此時每個函數都引用著保存變量i的同一個變量對象,所以每個函數內部i的值都是10。 我們可以通過創建一個匿名函數強制讓閉包行為符合預期。
function createFunction(){ var result = new Array(); for(var i=0; i<10;i++){ result[i]=function(num){ return function(){ return i; }; }(i); } return result; }在這個函數中,我們沒有直接閉包復制,而是定義了一個匿名函數,并將立即執行該匿名函數的結果賦值給數組。這里的匿名函數有一個參數num,也是最終函數要返回的值。在調用匿名函數時,我們傳入了變量i,由于函數參數是按值傳遞的,所以就會將變量i的當前值復制給num,而這個匿名函數內部,又創建并返回了一個訪問num的閉包。 這樣一來,result數組中的每個函數都有自己的num變量的一個副本,因此就可以返回各自不同的數值了。
新聞熱點
疑難解答