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();

浙公网安备 33010602011771号