本文仅就这一问题展开讨论,阅罢本文,读者若能正确回答 JavaScript 中的 What 's this 问题,作为作者,我就会觉得花费这么多功夫,撰写这样一篇文章是值得的。
我们要记住一句话:this永远指向函数运行时所在的对象!而不是函数被创建时所在的对象。也即:谁调用,指向谁。切记…
本文将分
三种情况来分析this对象到底身处何方。
1、普通函数中的this 无论this身处何处,第一要务就是要找到函数运行时的位置。当this出现在全局环境的函数getName中时,此时函数getName运行时的位置在
显然,函数getName所在的对象是全局对象,即window,因此this的安身之处定然在window。此时的this指向window对象,则getName返回的this.name其实是window.name,因此alert出来的是“全局”!
那么,当this不是出现在全局环境的函数中,而是出现在局部环境的函数中时,又会身陷何方呢?
其中this身处的函数getName不是在全局环境中,而是处在xpg环境中。无论this身处何处,一定要找到函数运行时的位置。此时函数getName运行时的位置
显然,函数getName所在的对象是xpg,因此this的安身之处定然在xpg,即指向xpg对象,则getName返回的this.name其实是xpg.name,因此alert出来的是“局部”!
举个例子巩固一下:
name: "Tom",showName: someone.showName
}
other.showName(); //Tom
this关键字虽然是在someone.showName中声明的,但运行的时候是other.showName,所以this指向other.showName函数的当前对象,即other,故最后alert出来的是other.name。
2、闭包中的this
闭包也是个不安分子,本文暂且不对其过于赘述,简而言之:所谓闭包就是在一个函数内部创建另一个函数,且内部函数访问了外部的变量。 浪子this与痞子闭包混在一起,可见将永无宁日啊!
此时的this明显身处困境,竟然处在getName函数中的匿名函数里面,而该匿名函数又调用了变量name,因此构成了闭包,即this身处闭包中。 无论this身处何处,一定要找到函数运行时的位置。此时不能根据函数getName运行时的位置来判断,而是根据匿名函数的运行时位置来判断。
显然,匿名函数所在的对象是window,因此this的安身之处定然在window,则匿名函数返回的this.name其实是window.name,因此alert出来的就是“全局”!
那么,如何在闭包中使得this身处在xpg中呢?—缓存this
在getName函数中定义that=this,此时getName函数运行时位置在
则this指向xpg对象,因此that也指向xpg对象。在闭包的匿名函数中返回that.name,则此时返回的that.name其实是xpg.name,因此就可以alert出来 “局部”!
3、new关键字创建新对象
new关键字后的构造函数中的this指向用该构造函数构造出来的新对象:
var Bob = new Person("Bob");
Bob.show(); //Bob
4、call与apply中的this
在JavaScript中能管的住this的估计也就非call与apply莫属了。 call与apply就像this的父母一般,让this住哪它就得住哪,不得不听话!当无参数时,当前对象为window
其中this身处函数getName中。无论this身处何处,一定要找到函数运行时的位置。此时函数getName运行时的位置
显然,函数getName所在的对象是window,因此this的安身之处定然在window,即指向window对象,则getName返回的this.name其实是window.name,因此alert出来的是“全局”!
那么,该call与apply登场了,因为this必须听他们的指挥! getName.call(xpg); 其中,call指定this的安身之处就是在xpg对象,因为this被迫只能在xpg那安家,则此时this指向xpg对象, this.name其实是xpg.name,因此alert出来的是“局部”!
5、eval中的this
对于eval函数,其执行时候似乎没有指定当前对象,但实际上其this并非指向window,因为该函数执行时的作用域是当前作用域,即等同于在该行将里面的代码填进去。下面的例子说明了这个问题:
name: "Bob",showName: function(){
eval("alert(this.name)");
}
};
Bob.showName(); //Bob
6、没有明确的当前对象时的this
当没有明确的执行时的当前对象时,this指向全局对象window。 例如对于全局变量引用的函数上我们有:
name: "Bob",show: function(){
alert(this.name);
}
}
var show = Bob.show;
show(); //Tom
你可能也能理解成show是window对象下的方法,所以执行时的当前对象时window。但局部变量引用的函数上,却无法这么解释:
name: "Bob",showName: function(){
alert(this.name);
}
};
var Tom = {
name: "Tom",showName: function(){
var fun = Bob.showName;
fun();
}
};
Tom.showName(); //window
在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,这条我们可以看成是上一条的一个特殊情况。
所以在运行this.showName的时候,this指向了window,所以最后显示了window.name。
7、dom事件中的this
(1)你可以直接在dom元素中使用