javascript中的this
javascript中的this跟java、c#中的this差距比较大,对于this的了解直接可以看出,这个人javascript的水平和以后能发展成什么样子?
现在来说一下javascript中的this;
this指向哪里?
一般而言,在Javascript中,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
你可能也能理解成show是window对象下的方法,所以执行时的当前对象时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,这条我们可以看成是上一条的一个特殊情况。
所以在运行this.showName的时候,this指向了window,所以最后显示了window.name。
浏览器中全局变量可以当成是window对象下的变量,例如全局变量a,可以用window.a来引用。我们将代码改成匿名函数可能更好理解一些:
例如:
var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ alert(this.name); }, waitShowName : function(){ !function(__callback){ __callback(); }(this.showName); } }; nameObj.waitShowName(); //Bob
说明:
在调用nameObj.waitShowName时候,我们运行了一个匿名函数,将nameObj.showName作为回调函数传进这个匿名函数,然后匿名函数运行时,运行这个回调函数。由于匿名函数的当前对象是window,所以当在该匿名函数中运行回调函数时,回调函数的this指向了window,所以alert出来window.name。
setInterval也如此类比。
但如果我们的确想得到的回答是Tom呢?通过一些技巧,我们能够得到想要的答案:
例如:
var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ alert(this.name); }, waitShowName : function(){ var that = this; setTimeout(function(){ that.showName(); }, 1000); } }; nameObj.waitShowName(); //Tom
说明:在执行nameObj.waitShowName函数时,我们先对其this赋给变量that(这是为了避免setTimeout中的匿名函数运行时,匿名函数中的this指向window),然后延迟运行匿名函数,执行that.showName,即nameObj.showName,所以alert出正确结果Tom。
eval
对于eval函数,其执行时候似乎没有指定当前对象,但实际上其this并非指向window,因为该函数执行时的作用域是当前作用域,即等同于在该行将里面的代码填进去。下面的例子说明了这个问题:
var name = "window"; var Bob = { name: "Bob", showName: function(){ eval("alert(this.name)"); } }; Bob.showName(); //Bob
apply和call
apply和call能够强制改变函数执行时的当前对象,让this指向其他对象。因为apply和call较为类似,所以我们以apply为例:
例如:
var name = "window"; var someone = { name: "Bob", showName: function(){ alert(this.name); } }; var other = { name: "Tom" }; someone.showName.apply(); //window someone.showName.apply(other); //Tom
说明:apply用于改变函数执行时的当前对象,当无参数时,当前对象为window,有参数时当前对象为该参数。于是这个例子Bob成功偷走了Tom的名字。
new关键字
new关键字后的构造函数中的this指向用该构造函数构造出来的新对象:
function Person(__name){ this.name = __name; //这个this指向用该构造函数构造的新对象,这个例子是Bob对象 } Person.prototype.show = function(){ alert(this.name); } var Bob = new Person("Bob"); Bob.show(); //Bob
先总结这么多,欢迎大家讨论!!!!!!!!!!!!!!!!!!!!!