①闭包只包含任何变量的最后一个值,即闭包返回的是对包含函数(外部函数)的活动对象(变量对象)的引用,所以在执行闭包函数时里面引用的变量返回执行前的最后值。
如下:
function creatArr(){
var result = [];
for (var i = 0; i<5; i++){
result[i] = function(){
return i;
}
}
return result;
}
此时返回的result 中的值全为 5 ;而不是我们需要的 [ 0 ,1 ,2 ,3 ,4]
解决办法为为每个数值定义匿名函数且立即执行返回当前 i 值;
如下:
function creatArr(){
var result = [];
for (var i = 0; i<5; i++){
result[i] = (function(j){
return j;
})(i);
}
return result;
}
②闭包中this对象的特殊处理:
如下闭包函数,执行this.name 输出了全局变量name,
var name = 'window';
var object = {
name:'object',
fnGetName: function(){
return function(){
return this.name;
}
}
}
alert(object.fnGetName()()); //window
分析,在全局环境下调用object.fnGetName(),返回了匿名函数(指向this.name ),此时再执行此匿名函数,因为匿名函数的执行环境具有全局性,故this指向window,则this.name 指向全局变量name ;
若要返回object中的name属性,可把this对象保存在一个变量中,避免在匿名函数中直接调用this,即可避免this指向window的问题,如下:
var name = 'window';
var object = {
name:'object',
fnGetName: function(){
var that = this ;
return function(){
return that.name;
}
}
}
alert(object.fnGetName()()); //object
③内存泄露:如果闭包中包含了一个HTML元素,那么该元素将无法被销毁。
如下代码:
function handlerElement(){
var element = document.getElementById('');
element.onclick = function(){
alert(element.id);
}
}
如上,element元素的处理程序是匿名函数,且该匿名函数中对element有引用,如此便导致了循环引用,由于匿名函数的执行环境具有全局性,因此只要匿名函数存在就有对element的引用,它所占的内存就不可回收。
解决:把element.id保存一个副本,在匿名函数中引用该副本即可消除闭包中的循环引用。又闭包包含整个包含函数(外部函数)的活动对象,因此对element还有一次引用,应该最后再把element置空,便可彻底解除对element 的引用。
如下:
function handlerElement(){
var element = document.getElementById('');
var id = element.id;
element.onclick = function(){
alert(id);
}
element = null;
}
Javascript 闭包细节整理
最新推荐文章于 2024-08-22 14:32:34 发布