一直想把閉包相關的東西整理出來,這篇文章算是閉包相關知識的最終版。
主要分下面幾個大的方面:
一、定義及運行 二、特性 三、內存洩露和監控 四、應用
下面詳細說下。
一、定義及運行
下面是在百度的時候,做的一次相關分享,可以不妨掃一掃這個ppt,在ppt後,我再提取關鍵信息。
我再抽取一下關鍵的信息:
對於閉包的定義很多書籍都很模糊,個人認為比較准確的定義——
閉包是函數的代碼在運行過程中的一個動態環境
函數和閉包要有非常清晰的對比——
一個函數只是一段靜態的代碼、腳本文本,因此它是一個代碼書寫時,以及編譯期的、靜態的概念;而閉包則是函數的代碼在運行過程中的一個動態環境,是一個運行期的、動態的概念。 閉包作為與函數成對的數據,在函數執行過程中處於激活(即可訪問)狀態(通俗來講,就是當執行到函數的某一條語句的時候,哪些對象能夠被使用)。
還有一點,就是閉包的實現方式——
JavaScript使用作用域鏈來實現閉包,作用域鏈由執行環境維護,JavaScript中所有的標識符都是通過作用域鏈來查找值的。
二、特性
閉包最為核心的特性便是保存狀態,源於活動對象(VO)中所有的變量均置於內存之中,相對而言,激活對象(AO)中的所有變量,在函數執行完成之後,將被垃圾回收器處理。
再具體的東西,在此就不細說了,主要理解了閉包的定義自然就理解它的這個特性。
三、內存洩露及監控
這點,我做的不夠充分。先引入幾篇文章——
JavaScript Memory Leaks(對應的中文翻譯:JavaScript內存洩露):這篇文章主要講解JavaScript導致內存洩露的幾個原因,其中一條便是閉包的使用。
JavaScript內存分析:這篇文章主要講解如何使用chrome的開發者工具進行內存的分析
這個是司徒正美推薦的一個內存洩露分析的工具——javascript 內存洩露工具使用,在這兒也推薦推薦。
四、應用
這裡優先推薦Barret Lee的文章——JS閉包的用途,在這兒重點強調一下:
1. 匿名自執行函數:或者可以理解為,避免污染全局變量 2. 緩存:源於閉包的核心特性便是保存狀態,應用此特性便可對需要的變量進行緩存 3. 實現封裝:同樣可以使用閉包保存狀態的特性,充當一個作用域塊,將塊裡面的屬性變量至於內存之中來實現封裝 4. 閉包的另一個重要用途是實現面向對象中的對象,傳統的對象語言都提供類的模板機制:原理同上
總之,這些均是基於閉包的保存狀態特性來實現。
五、總結
OK,閉包的話題一直纏繞前端JavaScript理論中的明星話題,並不是一朝一夕就可以理解透徹的,希望看到的同學,多在實踐當中思考閉包的種種。