主要分三部分说:
一、什么是闭包?二、闭包有什么好处?应用在哪里?三、闭包需要注意的地方?
1、什么是闭包?
第一个特点:可以是函数嵌套函数
function a(){
function b(){}
}
第二个特点:内部函数可以引用外部函数的参数和变量
function a(a){
var b=5;
function b(){
alert(a);
alert(b);
}
}
a和b两个变量都要被内部函数b()引用到,会一直驻扎在内存中,不会被垃圾回收的,也就是说参数和变量不会被垃圾回收机制所收回。
那么什么是js垃圾回收机制呢?
function a(){
var a=1;
}
alert(a);
例如,上面写了个普通函数a(),当alert(a)执行完毕后,调用完毕后变量a就不存在了,为了节省内存。
例子:
function a(){
var a=5;
function b(){
alert(a);
}
return b;
}
var c=a();
c(); //5
变量c就是返回的b函数,c()执行的时候 变量a并没有消失,一直驻扎在内存中的,这时会弹出5的.这就是简单的闭包形式。
2、闭包有什么好处?应用在哪里?
好处就:
1.希望一个变量长期驻扎在内存当中
2.避免全局变量的污染
var a=1;
function a(){
a++;
alert(a);
}
a(); //2
a(); //3
alert(a);//1
a是个全局变量,一直驻扎在内存中,依次执行会累加。
function a(){
var a=1;
a++;
alert(a);
}
a(); //2
a(); //2
如果把变量a设置为局部变量,每调用一次代码重新执行,调用后a就不存在,下次调用的时候a还是1;那么怎么能做到a即是局部变量,a又能累计呢?
这就是闭包所能做到的。
例2
function a(){
var a=1;
return function () {
a++;
alert(a);
};
}
var b=a();
b(); //2
b(); //3
alert(a) //undfined
构成了函数嵌套函数,当外面的函数执行完毕后,内部函数依旧可以调用到变量a;
说一下函数声明和函数表达式:
function a(){
alert(1);
}
//函数声明
a();
//函数调用
这样就是函数声明和函数调用;
(function(){
alert(1);
})();
()放函数,函数声明就会变成函数表达式,加()直接调用,可以执行。
至此可以把例2中的代码改写一下
var a= (function () { var a=1; return function () { a++; alert(a); } })(); a();//2 a();//3
var a=1在外面是调用不到的,这种形式叫做模块化代码,减少全局变量的污染,把内部函数变为私有的,
这也就是
3.私有成员的存在(用法)
var aaa = (function(){ var a = 1; function bbb(){ a++; alert(a); } function ccc(){ a++; alert(a); } return { b : bbb, c : ccc } })(); //aaa.b(); //2 //aaa.c(); //3
在循环中直接找到对应元素的索引
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> <li>11111111111</li> <li>11111111111</li> <li>11111111111</li> </ul> <script> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for(var i=0;i<aLi.length;i++){ aLi[i].onclick = function(){ alert(i);//3 }; }; }; </script> </body> </html>
alert(i)弹出3,为什么呢?很明显,当循环执行结束的时候
aLi[i].onclick = function(){ alert(i);//3 }; };
还没执行,当点击的时候才会执行,但此时i已经变成3了。可以利用闭包改写,可以把循环中的i当作个参数穿进去,就之前所说的内部函数可以引用外部函数的参数和变量。
for(var i=0;i<aLi.length;i++){ (function(i){ aLi[i].onclick = function(){ alert(i); }; })(i);
把i当成参数穿进去。除了这种写法还有另外一种方式
for(var i=0;i<aLi.length;i++){ aLi[i].onclick = (function(i){ return function(){ alert(i); } })(i);
闭包需要注意的IE下会引发内存泄漏
http://www.cnblogs.com/xhk-yjp/archive/2012/08/29/xhk-yjp-jsbb.html