1. 程式人生 > >閉包(簡單理解)

閉包(簡單理解)

閉包的學習

  • 閉包就是一個函式引用另外一個函式的變數,因為變數被引用著所以不會被回收,因此可以用來封裝一個私有變數。這是優點也是缺點,不必要的閉包只會徒增記憶體消耗!另外使用閉包也要注意變數的值是否符合你的要求,因為他就像一個靜態私有變數一樣。閉包通常會跟很多東西混搭起來,接觸多了才能加深理解,這裡只是開個頭說說基礎性的東西。

一個小小的例項

function buildList(list) {
 var result = [];
 for(var i = 0; i < list.length; i++) {
  var item = 'item' + list[i];
  result.push( 
    (function(i) {
      console.log(item + ' ' + list[i]);
    })(i)
   );
 }
 return result;
}
 
var fnlist = buildList([1,2,3]);

記憶體洩漏

其實呢,大家所熟知的閉包會造成記憶體洩漏,就是記憶體被佔用,無法騰出空間做其他的操作。這就牽扯到了瀏覽器的垃圾回收機制,下面就來說說垃圾回收機制到底是什麼東西。

瀏覽器的垃圾回收機制分為兩種;

  1. 其一:標記清除。具體就是當瀏覽器執行js時,會給所有的變數,或者佔用空間記憶體的其它東西全部加上標記(就是一個記號,不需要過多研究),執行中當變數被引用到,該變數的標記會被去掉,到最後還存有標記的變數說明已經沒有用了,瀏覽器會把它清除掉,並且收回佔用的空間,瀏覽器會不斷地重複執行,所以當變數不用時最終還是會被清除掉,,。而閉包裡面的變數受到保護,處於一直被佔用狀態,也就標記不上了,在記憶體中也就一直佔用
  2. 其二:引用計數。引用計數的含義是跟蹤記錄每個值被引用的次數,當宣告一個變數並將一個引用型別的值賦給該變數時,這個時候的引用型別的值就會是引用次數+1了。如果同一個值又被賦給另外一個變數,則該值的引用次數又+1。
    相反如果包含這個值的引用的變數又取得另外一個值,即被重新賦了值,那麼這個值的引用就減一。當這個值的引用次數程式設計0時,表示沒有用到這個值,這個值也無法訪問,因此環境就會收回這個值所佔用的記憶體空間回收。這樣,當垃圾收集器下次再執行時,它就會釋放引用次數為0的值所佔用的記憶體。

如果看到這裡還不知道閉包的記憶體洩漏的話,只有一個原因,那就是閉包內部變數的作用域,還不是很清楚。