请看下面的代码,最后alert出来的是什么呢?
var name = "Bob";
var nameObj ={
name : "Tom",
showName : function(){
alert(this.name);
},
waitShowName : function(){
setTimeout(this.showName, 1000);
}
};
nameObj.waitShowName();
上述的例子弹出的Bob而不是tom
要解决这个问题我们需要了解Javascript的this关键字的用法。
this指向哪里?
一般而言,在Javascript中,this指向函数执行时的当前对象。值得注意,this在Javascript指向的是执行环境,而非声明环境有关。
我们举个例子来说明这个问题:
var someone = {
name: "Bob",
showName: function(){
alert(this.name);
}
};
var other = {
name: "Tom",
showName: someone.showName
}
other.showName(); //Tom
this关键字虽然是在someone.showName中声明的,但运行的时候是other.showName,所以this指向other.showName函数的当前对象,即other,故最后alert出来的是other.name。
没有明确的当前对象时
当没有明确的执行时的当前对象时,this指向全局对象window。
例如对于全局变量引用的函数上我们有:
var name = "Tom";
var Bob = {
name: "Bob",
show: function(){
alert(this.name);
}
}
var show = Bob.show;
show(); //Tom
Bob.show();//Bob
你可能也能理解成show是window对象下的方法,所以执行时的当前对象时window。
但局部变量引用的函数上,即:在方法的方法中调用this的话默认指向的都是全局作用域,即window:
var name = "window";
var Bob = {
name: "Bob",
showName: function(){
alert(this.name);
}
};
var Tom = {
name: "Tom",
showName: function(){
var fun = Bob.showName;
fun();
}
};
Tom.showName(); //window
setTimeout、setInterval和匿名函数
在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,这条我们可以看成是上一条的一个特殊情况。这种特殊情况也属于javascript的设计缺陷。所以在运行this.showName的时候,this指向了window,所以最后显示了window.name。针对上述例子,要想弹出Bob,修改如下:
var name = "window";
var Bob = {
name: "Bob",
showName: function(){
alert(this.name);
}
};
var Tom = {
name: "Tom",
showName: function(){
//此处不要用在做一次匿名函数引用的赋值即可,直接使用对象本身来调用,这样,在执行此处时,属于Bob对象在运行(切记:this关键字指向的是执行环境)
Bob.showName();
}
};
Tom.showName();//Bob