在javascript中,有許多閉包的運用。javascript
1. 事件響應函數java
var divs = document.getElementsByTagName('div'); for(var i=0; i<3; i++){ divs[i].onclick = function(){ alert(i); } }
此例中,假設爲3個div元素添加onclick事件,咱們會發現不管點擊哪個div都會輸出3。這是由於咱們爲div綁定的onclick事件處理函數就是一個閉包,它能夠訪問到這個函數定義時所處做用域中的變量。而且事件響應是異步觸發的,當點擊某一個div時,實際上外層循環已經結束了,i的值始終爲3。設計模式
要修改這個bug能夠引進一個當即執行的匿名函數,將當前的i值傳入:閉包
for(var i=0; i<3; i++){ function(i){ divs[i].onclick = function(){ alert(i); } }(i); }
2. 封裝變量異步
有時候咱們須要用一個全局變量來存儲一些在整個程序運行過程當中都須要被保存下來的值,例如一組人名和Id對應。函數
var persons = {}; var addPerson = function (name,id){ if(persons.hasOwnProperty(name)){ return false; } else { persons[name] = id; return true; } }
假設只有在addPerson這個函數中咱們用到了persons這個變量,就沒有必要將其暴露給其餘的函數以防止沒必要要的變量衝突,可是又不能直接將其定義在函數內部,不然會隨着函數執行完畢而消失。這個時候就須要用到閉包了。修改代碼以下:設計
var addPerson = (function (){ var persons = {}; return function(name,id){ if(persons.hasOwnProperty(name)){ return false; } else { persons[name] = id; return true; } } })();
此例中,咱們將persons封裝在addPerson函數內部,而且經過在一個當即執行的匿名函數內部return一個閉包函數使得addPerson被賦值的這個函數(即return的函數)能夠訪問到persons這個變量。code
相比於直接在addPerson函數內部定義persons這個變量,咱們一樣經過閉包延續了變量的生存週期,使其不至於由於函數執行結束而被銷燬。事件
參考《javascript開發實踐與設計模式》。ip