JS中的闭包
对于闭包,普遍的说法是“函数嵌套的函数”,我认为,可以理解为可以调用外部变量的函数,在ECMAScript中有提到,使用全局变量是一个简单的闭包实例。内部函数就是一个闭包,因为它可以获取外部函数的参数及变量,全局变量的值。
闭包的作用在于:1.解决因垃圾回收机制而使局部变量无法长期驻扎在内存中的问题;
2.减少全局变量的污染;
它可以:1.实现变量的累加;2.在循环中找到对应元素的索引;3......(还有很多)
那什么是垃圾回收机制呢?
JS为了减少内存占用,函数的局部变量在函数调用后会被清除
function aaa () {
var a = 1;
a++;
alert(a);
}
aaa(); //2
aaa(); //2
可以看出,调用后变量a被清除,再次调用时才被赋值,因此无法实现累加的效果,可通过闭包实现累加。
什么是全局变量污染呢?
var a = 1;
function aaa () {
a++;
alert(a);
}
aaa(); //2
aaa(); //3
alert(a); //3
可以看出,此时虽然可以实现累加,但是全局变量被改变,即此时全局变量a只能被函数aaa()使用,不可以其他函数使用,否则互相修改,不确定且变化的值会使程序功能的实现出现问题。
闭包的写法又是怎样的呢?
function aaa () {
var a = 1;
return function () {
a++;
alert(a);
}
}
var b = aaa ();
b(); //2
b(); //3
此时a为局部变量,所以不会污染的全局变量~
闭包还有个不错的用法:模块化代码
作用:将内部函数私有(利用括号将函数变为自执行的函数表达式)
(function aaa () {
//do something...
})() //可传参
还可以这样:
var aaa = (function () {
var a = 1; //私有成员
function bbb () { //私有方法bbb
a++;
alert(a);
}
function ccc () { //私有方法ccc
a++;
alert(a);
}
return{
b:bbb,
c:ccc
}
})();
aaa.b(); //2
aaa.c(); //3
alert(a); //报错
alert(bbb); //报错
alert(ccc); //报错
气人的IE,委屈的闭包
差点忘了,闭包也不都是好的,由于早期IE的垃圾回收机制是使用引用计数垃圾回收的方式,简单的说就是使用一个计数器记录数据被引用的次数,如果为0则清除,这样当有互相引用的情况出现时就会出现内存泄漏,所谓的内存泄漏,即计数器不会为0,只要浏览器不被关闭就不会被清除,一直留在内存中,我们可以看到的就是浏览器越来越慢越来越慢,可你就是不知道浏览器到底发什么疯得什么病了,如果是你自己的网站,那最好看看是否是内存泄漏了~
互相引用的情况:dom节点或获取的数组对象的属性引用内部函数,内部函数的变量又引用外部时就会出现互相引用的情况,此时就会出现内存泄漏。
例子:
window.onload = function () {
var oDiv = document.getElementById ('div1'); //dom元素
oDiv.onclick = function () { //被引用
alert (oDiv.width);
};
};
解决方案1:
window.onunload = function () {
oDiv.onclick = null; //在关闭网页时清空回收
};
解决方案2:
window.onload = function () {
var oDiv = document.getElementById('div1');
var w = oDiv.width;
oDiv.onclick = function () {
alert (w);
};
oDiv = null; //清空,使被回收
};
至于HTML,CSS部分,请自行脑补~