在javascript中,有很多闭包的应用。
1. 事宜响应函数
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这个变量。
比拟于直接在addPerson函数内部定义persons这个变量,我们一样经由过程闭包连续了变量的生计周期,使其不至于由于函数实行终了而被烧毁。
参考《javascript开辟实践与设想形式》。