您当前的位置: 首页 > 学无止境 > JS经典实例 网站首页JS经典实例
javascript匿名函数与闭包-匿名函数与闭包【中】
发布时间:2016-10-21 16:27:08编辑:雪饮阅读()
对闭包匿名函数数组遍历取值问题:
function box(){
var arr=[];
for(var i=0;i<5;i++){
arr[i]=function(){
return i;
}
}
return arr;
}
var b=box();
for(var i=0;i<5;i++){
alert(b[i]());
}
该案例以闭包的形式将多个匿名函数存储于一个数组中,然后遍历该闭包的匿名函数数组并传递以i参数使其每个匿名函数返回不同的值
但实际上每个匿名函数都返回的是普通函数box中循环的i的上限值+1
分析:
在for循环中i的值会被当中一个变量存储下来,而且该变量不仅仅for循环体内可以访问,如下:
function box(){
for(var i=0;i<5;i++){
alert(i);
}
alert("结束:"+i);
}
box();
另外b=box()已将外层普通函数驻留内存中了,只执行一次不会二次初始化,b=box()已经将里面的循环体中i变量最终加到5了,之后才返回的匿名函数数组
而在b=box()之后的这次循环中b[i]()中i是读取外层普通函数中的局部变量值的值(已经驻留为5),所以最后循环的值都是5
解决方案:
function box(){
var arr=[];
for(var i=0;i<5;i++){
//采用带参数的匿名函数及时执行
arr[i]=(function(num){
return num;
})(i);
//带参数的匿名参数及时执行完毕
}
return arr;
}
var b=box();
for(var i=0;i<5;i++){
alert(b[i]);
}
匿名函数的另类自我执行:
匿名函数当要赋值一个变量时可以不需要第一对括号(原本存放函数声明的),而是直接声明函数,然后直接在函数声明完毕补上第二对括号即可:
var a=function (){
alert('aa');
}()
闭包中this对象指向的是windows如:
var box={
getThis:function(){
return function(){
return this;
}
}
}
alert(box.getThis()());
那么闭包中使用this调用属性也就是全局的属性:
var user='The Window';
var box={
user:'The Box',
getUser:function(){
return function(){
return this.user;
}
}
}
alert(box.getUser()());
更改闭包中this指向由全局变成当前对象:
方法一:对象冒充
只需要在调用的时候进行对象冒充即可:alert(box.getUser().call(box));
方法二:作用域转交
var user='The Window';
var box={
user:'The Box',
getUser:function(){
var that=this;//作用域转交给that
return function(){
return that.user;
}
}
}
alert(box.getUser()());
闭包的内存泄漏(主要是ie浏览器):
<div id="oDiv">雪饮</div>
<script>
function box(){
var oDiv=document.getElementById("oDiv");
oDiv.onclick=function(){
alert(oDiv.innerHTML);//这里导致内存泄漏
}
alert(oDiv);
}
box();
</script>
内存泄漏,导致浏览器dom对象被驻留内存没有得到释放,而实际上我们只是为了得到点击时获取div的innerHTML而已。那么我们要改进下box函数:
function box(){
var oDiv=document.getElementById("oDiv");
var text=oDiv.innerHTML;//在对象中取值给一个局部变量
oDiv.onclick=function(){
alert(text);
}
oDiv=null;
alert(oDiv);//销毁对象
}
关键字词:javascript,匿名函数,闭包