闭包是一个受保护的变量空间,由内部函数生成。
闭包的变量始终不会被释放,除非手动释放,这也是闭包的一个缺陷
function getCount(){
var count=0;
function autoAdd (){
count++;
console.log(count);
}
return autoAdd
}
var c=getCount();
c();
c();
c();
c = null;
c=getCount();
c();
这代码输出的结果为:1、2、3、1.
当c=null;手动置空的时候,闭包里的值才会被清空。
我们再来逐步分析下闭包:
var test = function(){
var index = 1;
var closure = function(){
alert(index) ;//output: 1
}
};
且看上面这个代码,在闭包closure中index=1,也就是说在closure内部是可以访问到外部的值的。
再看一个完整的代码
var test = function(){
var index = 1;
var closure = function(){
alert(index) ;//output: 1
}
return closure;
};
1:var exec = test();//请看代码,test()返回的是一个function,在此执行test()方法时,已经声明了index变量,一般程序在执行完方法之后,内部变量(局部变量)会被自动垃圾回收的,当你第二次执行方法的时候,再重新声明变量赋值等。全局变量是要在关闭浏览器等等的时候才会去销毁。
2:exec();//因为是function 所以加上括号可以让其执行
上面1,2两步简化下可以写成test()();
var test = function(){
var index = 1;
alert(data); //如果想在这里调用closure 中声明的data是不允许的,这里会输出undefined
var closure = function(){
alert(index) ; //output: 1
var data = "123456";
}
return closure;
};
然后我们看一个经典的闭包问题。
function test(){
var elements = document.getElementByClassName("class");
for(var i=0; i<elements.length; i++){
elements[i].onclick = function(){
alert(i);//这里会一直output elements.length-1
}
}
}
看其根本,其实onclick就是一个内部函数,也就是一个闭包。那么闭包里的变量 i 会保存外部变量 i 的值,所以会一直输出elements.length-1。
那么怎么样解决alert(i)和for循环里面的 i 保持一致呢?
function test(){
var elements = document.getElementByClassName("class");
for(var i=0; i<elements.length; i++){
elements[i].onclick = (function(index){
alert(index);//这样就能完美解决这个问题啦。
//(function(){})()是一个立即执行函数,相关知识请点击这里
})(i);// 变量 i 被传递给index
}
}