JavaScript关于匿名函数和闭包及IE中闭包导致的内存泄漏

匿名函数相关知识点

普通函数
function box(){
return 'Lee';
}
alert(box());

匿名函数
function(){ //单独的匿名函数无法运行,就算能运行也无法调用,因为没有名称
return 'Lee';
}
alert(box()); //无法调用,因为没有名称


匿名函数赋值给变量
var box=function(){
return 'Lee';
};
alert(box) //打印出函数
alert(box()); //Lee


//通过自我执行来执行匿名函数
(function(){ //(匿名函数)(); //第一个圆括号放匿名函数,第二个圆括号执行
alert('Lee');
})();

//把匿名函数的自我执行返回值赋给变量
var box=(function(){
return 'LOG2E0';
})();
alert(box); //LOG2E0

//自我执行后用alert打印
alert((function(){
return 'LOG2E0';
})()); //LOG2E0

//自我执行后传参后用alert打印
alert((function(name){
return name;
})('aaaaaa'));


//函数里放一个匿名函数
function box(){
return function(){ //这个就是闭包
return 'Lee';
}
}
//体会三个差别
alert(box); //输出box()函数
alert(box()); //输出匿名函数
alert(box()()); //输出Lee

 

---------------------------------------------------------------------------------

闭包

//使用闭包返回局部变量
function box(){
var age=50;
return function(){
return age;
};
}
alert(box()());

//使用局部变量进行累加
function box(){
var age=100;
age++;
return age;
}
alert(box()); //101
alert(box()); //还是101 因为局部变量一直被初始化





//使用匿名函数实现局部变量驻留内存中从而实现累加
function box(){
var age=100;
return function(){
age++;
return age;
};
}
var b=box(); //调用一次,从而让age不会被多次初始化
alert(b()); //101
alert(b()); //102
alert(b());
alert(b());

b=null; //用完记得销毁,因为会常驻内存,解除引用,等待gcc



//循环里的匿名函数的取值问题
function box(){
var arr=[];

for(var i=0;i<5;i++){
arr[i]=function(){
return i;
};
}

//循环已经执行完毕,i最终式4++=5,那么最终就是5

return arr;
}
//alert(box()[1]());
//var b=box();
//for(var i=0;i<5;i++){
// alert(b[i]()); // 5 5 5 5 5
//}

var b=box();


//改0
function box(){
var arr=[];

for(var i=0;i<5;i++){
arr[i]=i;
}

return arr;
}

var b=box();
for(var i=0;i<5;i++){
alert(b[i]); // 0,1,2,3,4,
}

 

//改1
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]); //0,1,2,3,4
}

 

//改2 -----------用的多点
function box(){
var arr=[];

for(var i=0;i<5;i++){
arr[i]=(function(num){ //传给变量的话,自我执行自己的圆括号可以去,就是function前面的去掉
//num其实在这里
return function(){ //闭包可将变量驻留在内存中,和累加同个道理
return num;
}
})(i);
}

//已经执行完毕,为啥num还能0,1,2,3,4

return arr;
}

var b=box();
for(var i=0;i<5;i++){
alert(b[i]()); //0,1,2,3,4
}

 

---------------------------------------------------------------------------------------

闭包的this指向的对象是window;

//关于this对象
var box={
getThis:function(){
return function(){
return this;
}
}
};
alert(box.getThis()()); //[object Window] 闭包并不属于obj,是window对象

-----------------------------------------------

var user='THe Window';
var box={
user:'The Box',
getUser:function(){
return function(){
return this.user; //闭包指向全局的window
}
}
};

alert(user); // THe Window
alert(box.getUser()); //函数
alert(box.getUser()()); //THe Window

 


----------------------------------------------------
var user='THe Window';
var box={
user:'The Box',
getUser:function(){

//这里作用域的this是Box
var that=this;
return function(){

//这里作用域的this是Window
return that.user; //闭包指向全局的window
}
}
};
//对象冒充实现将this指向box
alert(box.getUser().call(box)); //The Box

//用作用域解决
alert(box.getUser()());//The Box

 

 

 --------------------------------------------------------------------------------------

 

//内存泄漏 --IE才存在的问题

function box(){
var oDiv=document.getElementById('oDiv');
oDiv.onclick=function(){
alert(oDiv.innerHTML)
};
alert(oDiv); //还驻留在内存中
oDiv=null; //解除引用,等待垃圾回收
alert(oDiv); //已经被回收,同时oDiv.onclick也消失了,无法再次点击
}
box();


//已经被回收,同时oDiv.onclick也消失了,无法再次点击的解决方法
function box(){
var oDiv=document.getElementById('oDiv');
var text=oDiv.innerHTML; //解决方法
oDiv.onclick=function(){
alert(text);
};
alert(oDiv); //还驻留在内存中
oDiv=null; //解除引用,等待垃圾回收
alert(oDiv); //已经被回收,同时oDiv.onclick也消失了,无法再次点击
}
box();

posted @ 2018-05-18 20:50  江小-白  阅读(339)  评论(0)    收藏  举报