在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