上一章我们讲了匿名函数和闭包,这次我们来谈谈闭包中作用域this的问题。
大家都知道,this对象是在运行时基于函数的执行环境绑定的,如果this在全局就是[object window],如果在对象内部就是指向这个对象,而闭包却是在运行时指向的window,因为闭包并不属于这个对象的属性和方法。
我们先来看一个例子关于全局作用域的问题:
var a = 'this is window';
var box = {
a:'this is object',
get:function () {
return this.a;
}
};
alert(this.a); //返回window.因为是全局作用域
不难看出,这个时候,this的作用域是全局的。指向的是window.结合上句话来看例子,如果在对象内部就是指向的这个对象。
var a = 'this is window';
var box = {
a:'this is object',
get:function () {
return this.a;
}
};
alert(box.get()); //返回的是this is object 因为这个是box对象下的作用域
我们了解了作用域的问题。接下来我们就说说闭包中this对象作用域的问题:
var a = 'this is window';
var box = {
a:'this is object',
get:function () {
return function () { //闭包
retun this.a;
};
}
};
alert(box.get()()); //返回this is window.
这就奇怪了,明明嵌套了这么多层,怎么会指向window呢,这就是闭包的机制,还是刚刚那句话:闭包却是在运行时指向的window,因为闭包并不属于这个对象的属性和方法。
那我们如何讲闭包的作用域指针指向对象内部呢?
两种方法:1.使用call()对象冒充,2.将作用域赋值给变量
/*对象冒充*/
var a = 'this is window';
var box = {
a:'this is object',
get:function () {
return function () { //闭包
retun this.a;
};
}
};
alert(box.get().call(box)); //返回 this is object
使用call()传值box,将box对象冒充。从而使作用域指向box对象内部。
/*将作用域赋值给变量*/
var a = 'this is window';
var box = {
a:'this is object',
get:function () {
/*这里的作用域是box,而不是window*/
var scope = this; //将作用域赋值给一个变量
return function () { //闭包
retun scope.a;
};
}
};
alert(box.get()()); //返回this is object.
IE浏览器中内存泄漏问题
大家都知道,闭包会使变量驻留在内存中,这也就导致了内存泄漏。但是只是针对IE浏览器,其他浏览器不会出现这种问题.
window.onload = function () {
function box () {
var div = document.getElementById('div');
div.onclick = function () {
alert(div.innerHTML);
};
}
box();
};
这里的互相调用会导致IE浏览器内存泄漏,因为div.onclick引用了上面的var div,他俩互相引用导致内存泄漏,解决办法就是将用完的div赋值null,等待垃圾回收
window.onload = function () {
function box () {
var div = document.getElementById('div');
var a = div.innerHTML;
div.onclick = function () {
alert(a);
};
a = null; //赋值为null,等待垃圾回收
}
box();
};
如果没有解除引用,必须等待浏览器关闭的时候才能释放!!!
关于作用域及内存泄漏的文章就到这里,欢迎老司机指正错误!
Brian Lee