1、什么是闭包?
函数嵌套函数
内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回
function fn1(){ var a = 5; function fn2() { alert(a); //内部函数使用外部函数的变量,不会被垃圾回收机制回收 } return fn2; } var c = fn1(); c(); /* 结果:5 fn1(),返回结果为fn2函数,即function fn2() { alert(a) }; c(),调用fn2函数 也可以这样写:fn1()(),fn1()=fn2 */
2、闭包的好处?应用在哪里?
好处:
希望一个变量长期驻扎在内存当中
避免全局变量的污染
私有成员的存在
/*全局变量*/
var a = 1;
function fn(){
a++; alert(a); } fn(); //2 fn(); //3 alert(a); //3 /*将以上改写成局部变量*/ function fn() { var a = 1; a++; alert(a); } fn(); //2 fn(); //2 alert(a); //出错 //以上结果是因为被垃圾回收机制回收了 /*a为局部变量,a又可以累加,采用闭包的方法*/ function fn1(){ var a = 1; function fn2() { a++; alert(a); } return fn2; } var c = fn1(); c(); //2 c(); //3 alert(a); //出错,因为是局部变量
//以上改写成如下:
function fn1(){
var a = 1;
return function(){
a++;
alert(a);
}
}
var c = fn1();
c(); //2
c(); //3
alert(a) //出错,因为是局部变量
/*
函数声明:
function fn(){
alert(1);
}
函数调用:
fn();
将“函数声明”改写成“函数表达式”:前面加上括号,括号内部为函数,需要调用直接后面加上括号,如下:
(function (){
alert(1);
})();
*/
//改写代码
var c = (function(){
var a = 1;
return function(){
a++;
alert(a);
}
})();
c(); //2
c(); //3
//以上的情况,模块化代码,减少全局变量的污染
//私有成员的存在 var test = (function(){ var a = 1; function fn1(){ a++; alert(a); } function fn2(){ a++; alert(a); } return { b:fn1, c:fn2 } })(); test.b(); //2 test.c(); //3 alert(a); //出错 alert(fn1()); //出错 alert(fn2()); //出错 //变量a、函数fn1和fn2为私有,以上为模块化代码的模式
用法:
模块化代码
在循环中直接找到对应元素的索引
3、闭包需要注意的地方
IE下会引发内存泄漏
(当页面跳转时,变量不会释放,一直存在内存当中,使CPU一直在累加,只有当浏览器关闭时才释放内存)
满足条件,如下例:一个变量(oDiv)获取DOM节点或数组对象的时候,它的一个属性(onclick)引用一个内部函数,而内部函数中这个变量(oDiv)又去引用外部的变量(oDiv),会产生内存泄漏
window.onload = function(){ var oDiv = document.getElementById('div'); oDiv.onclick = function(){ alert(oDiv.id); }
//解决内存泄漏问题
window.onunload = function(){
oDiv.onclick = null;
} }
方法二:
window.onload = function(){
var oDiv = document.getElementById('div');
var id = oDiv.id;
oDiv.onclick = function(){
alert(id);
}
oDiv = null;
}