js-闭包(妙版)

zccst整理

总结:
1,闭包是什么
闭包

2,闭包好处:
(1)希望一个变量长期驻扎在内存中。
(2)避免全局变量的污染。
(3)私有成员的存在

3,怎么用
模块化代码
例子
在循环中直接找到对应元素的索引
例子

4,可能存在的问题
内存泄露。外部变量与内部变量互相引用。导致内存越来越大。

解决办法:
1,及时释放dom结点对象。


闭包
定义:函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回。

function aaa(){
var a = 5;
function bbb(){
alert(a);
}
return bbb;
}
var c = aaa();
c();//5
c();//5

结论:变量一直存在。由于其参数和变量由于被内部函数使用,所以不会被收回。


垃圾回收机制

function aaa(){
var a = 12;
a++;
alert(a);
}
aaa();//13 即函数执行完之后,局部变量被回收。
aaa();//13 再次调用时,重新赋值。

alert(a);//a未定义,即离开作用域后,局部变量已被回收(外部不能访问)。


var a = 12;
function aaa(){
a++;
alert(a);
}
aaa();
aaa();
//问题是:污染了全局变量。如果连续调用aaa();则变量a的值会递增。



而我们既想使用局部变量,又想像全局变量一样累加(即闭包),则可如下所示:

//第一版:
function aaa(){
var a = 1;
return function(){
a++;
alert(a);
}
}
var b = aaa();
b();//2
b();//3

//第二版:把函数声明改写为函数表达式
var aaa = (function(){
var a = 1;
return function(){
a++;
alert(a);
}
})();

aaa();
aaa();



更进一步,把函数变私有,,即模块化代码。

var aaa = (function(){
var a = 1;
function bbb(){
a++;
alert(a);
}
function ccc(){
a++;
alert(a);
}
return { //json格式
b:bbb,
c:ccc
}
})();

aaa.b();//2
aaa.c();//3 a对于两个函数,相当于全局。


alert(a); //异常,未定义
alert(bbb);//异常,未定义
alert(ccc);//异常,未定义



在循环中直接找到对应元素的索引

window.onload = function(){
var aLi = document.getElementsByTagName("li");

//方式一:有问题
for (var i = 0; i < aLi.length; i++){
aLi[i].onclick = function(){
alert(i);
};
//问题:for循环后,i已经是4,所以所有li的click都是4。
}

//方式二:
for (var i = 0; i < aLi.length; i++){
(function(i){
//内部函数可以使用外包函数的参数和变量。
//外包函数执行完毕后,内部函数依然存在。
aLi[i].onclick = function(){alert(i);}
})(i);
}

//方式三:
for (var i = 0; i < aLi.length; i++){
aLi[i].onclick = (function(i){
//内部函数可以使用外包函数的参数和变量。
//外包函数执行完毕后,内部函数依然存在。
return function(){
alert(i);
}
})(i);
}

};
<ul>
<li>1111111111111</li>
<li>1111111111111</li>
<li>1111111111111</li>
<li>1111111111111</li>
</ul>



IE下引发内存泄露

window.onload = function(){
var oDiv = document.getElementById("div1");
oDiv.onclick = function(){
alert(oDiv.id);
}

//方法一:
window.unonload = function(){
oDiv.onclick = null;
}
}

//方法二:
window.onload = function(){
var oDiv = document.getElementById("div1");
var id = oDiv.id;//然后在内部函数中使用id,而不是oDiv即可解决
oDiv.onclick = function(){
alert(oDiv.id);
}
oDiv = null;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值