JavaScript 小記 之 閉包(Closures)

Closures are functions that refer to independent (free) variables.html

閉包是以靜態方式/詞法方式進行存儲全部父做用域的一個函數sublime-text

在JavaScript高級程序設計裏面經過一個 createComparisonFunction() 函數和這個函數的做用域鏈之間的關係圖說得很明白爲何閉包能夠訪問外部函數的變量, 是由於閉包的做用域鏈不只包括本身本地的活動對象, 還包括外部函數做用域鏈所指向的活動對象.數組

在JavaScript高級程序設計, JavaScript精粹 都有一個相似的例子 在循環裏建立閉包.閉包

(爲了測試, 作了一點點修改)函數

 1 var fn = function() {
 2     var result = [];
 3     for(var i = 0; i < 3; i++) {
 4         result[i] = function() {
 5             console.log(i);    
 6         };
 7     }
 8     return result; 
 9 };  
10 
11 var list = fn();
12 list[0]();   //3
13 list[1]();   //3
14 list[2]();   //3
 1 var fn = function() {
 2     var result = [];
 3     for(var i = 0; i < 3; i++) {
 4         result[i] = (function(num) {
 5             return function() {
 6                 console.log(num);
 7             };
 8         })(i);
 9     }
10     return result; 
11 };  
12  
13 var list = fn();
14 list[0]();   //0
15 list[1]();   //1
16 list[2]();   //2

當時爲了讓本身能夠了解得更完全 本身也把做用域鏈畫了出來 但願對部分同窗有用oop

第一個函數做用域關係圖:測試

從第一個函數的做用域關係圖能夠看出 之因此數組裏的每一個函數都打印3是由於每一個函數在各自本地的活動對象裏都找不到 i 因此繼續往上找 在外部函數的活動對象裏找到了i 可是此時的i 在循環結束後值爲3 因此每一個函數打印均爲3spa

第二個函數做用域關係圖:設計

第二個函數把一個當即執行的函數賦給了result數組, 並傳入了i 因此此時result[x]的活動對象裏就多一個變量num 值爲 i (函數參數按值傳遞) 因此返回的函數打印num時 根據做用域鏈找到了result[x] 活動對象裏的num 並打印出 num的值3d

 

經過畫這兩個函數的做用域鏈關係圖, 就能夠清楚地弄懂閉包的工做原理, 也就不會對閉包那麼懼怕啦! 

PS. 上面兩個例子在JSLint 裏都是會報錯的: Don’t make functions within a loop

因此你們在實際的程序當中就不要這樣使用 能夠在循環外變量定義函數後再在循環裏使用

最後附上 sublime-text 3 怎麼安裝SublimeLinter 的教程 http://www.sublimelinter.com/en/latest/installation.html

 

若有錯誤 歡迎指正 : ) 

相關文章
相關標籤/搜索