因为Javascript中函数的上下文关键字this是如何调用函数决定的,所以函数的上下文this决不能包含为闭包的一部分。当需要在闭包内使用函数的上下文this的时候就需要转换成that。
先来一个简单的例子,匹配所有元素(jquery)然后alert,"need_show":
...
this.id='need_show';
var that=this;
$('*').each(function(){
alert(that.id);
});
...
再从一个复杂的例子展开这个问题吧:
name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
上面的代码,很多时候大家都会搞错alert()的结果。
上面的代码,其实我们是希望,this能调用的是object内部属性"My Object",但第一种方法,却显示的是"The Window"。
在object的属性getNameFunc中使用this,是正确的。但大家注意,这个地方使用了一个return 匿名函数。也就是说,你在调用object.getNameFunc()(),这是其实相当于(function(){ return this.name; })(),这里的this当然就是window对象了。
解决方法,其实就是利用闭包,保存上下文this为that:
var object1 = {
name : "My Object",
getNameFunc : function(){
var that=this;
return function(){
return that.name;
};
}
};
alert(object1.getNameFunc()());
这就是为什么要引入一个that,that其实是保存了object正确上下文this。再调用object.getNameFunc()()时,就能正确了(function(){ returnthat.name; })();
经常看JS书的人,常常可以看到这个例子。我开始也不知道为什么,这里要用that。因为闭包的原因,确实让JS更加丰富了,当然难度和可读性也更高了。
再举个很值得玩味一下的例子:
function a(){
if ( !(this instanceof arguments.callee) )
return new a();
}
有了这个例子,我们就可以在调用函数a时,如果a没有实例化就创建一个新实例时,不用使用new关键字了。同样也是靠闭包才实现的(函数访问自身)。确实,从这种角度看,JS中创建的函数,其实就是构造函数。