请看下面的代码,最后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