當我們調用quo時,它傳回包含get_status方法的一個新對象。該對象的一個引用儲存在myQuo中。即使quo已經傳回了,但get_status方法仍然享有通路quo對象的status屬性的特權。get_status方法并不是通路該參數的一個副本,它通路的就是該參數本身。這是可能的,因為該函數可以通路它被建立時所處的上下文環境。這被稱為閉包。
了解内部函數能通路外部函數的實際變量而無須複制是很重要的
add_the_handlers函數的本意是想傳遞給每個處理器一個唯一值(i)。但它未能達到目的,因為事件處理器函數綁定了變量i本身,而不是函數在構造時的變量i的值。
避免在循環體中建立函數,它可能隻會帶來無謂的計算,還會引起混淆,正如上面那個糟糕的例子。我們可以先在循環之外建立一個輔助函數,讓這個輔助函數再傳回一個綁定了目前i值的函數,這樣就不會導緻混淆了。
複制下面的檔案到html檔案裡即可運作檢視效果!
閉包的好處有:
1.緩存
2.面向對象中的對象
3.實作封裝,防止變量跑到外層作用域中,發生命名沖突
4.匿名自執行函數,匿名自執行函數可以減小記憶體消耗
閉包的壞處:
1.記憶體消耗
通常來說,函數的活動對象會随着執行期上下文一起銷毀,但是,由于閉包引用另外一個函數的活動對象,是以這個活動對象無法
被銷毀,這意味着,閉包比一般的函數需要更多的記憶體消耗。尤其在IE浏覽器中需要關注。由于IE使用非原生javascript對象實作
DOM對象,是以閉包會導緻記憶體洩露問題。
2.性能問題
使用閉包時,會涉及到跨作用域通路,每次通路都會導緻性能損失。
是以在腳本中,最好小心使用閉包,它同時會涉及到記憶體和速度問題。不過我們可以通過把跨作用域變量存儲在局部變量中,然後直
接通路局部變量,來減輕對執行速度的影響。
記憶體洩露
1.定義:一塊被配置設定的記憶體既不能使用,也不能回收。進而影響性能,甚至導緻程式崩潰。
2.起因:JavaScript的垃圾自動回收機制會按一定的政策找出那些不再繼續使用的變量,釋放其占有的記憶體。然而由于一些原因
導緻在這種機制下記憶體管理器不能正确解讀javascript變量的生命周期,進而沒有釋放其記憶體,而也沒有再被使用。循環引用是
導緻以上情況的主要原因之一。
解決方法:常用的解決方法就是在JavaScript代碼段運作完之時将形成循環引用的JavaScript對象手動設定為空,切斷引用。
附加:一個朋友給了實作這個功能又不用閉包的方法
附加二:如果用ES6也可以