详细解读JavaScript的this关键字

2016-07-12

用了很久JavaScript,对【this】的认识只局限于以往的凭经验而已,不过今天发现了好东西“http://www.quirksmode.org/js/associative.html”,详细描述了如何使用【this】关键字,在这里我就简短的说一下重点,如果有疑问可以直接参考原文。

 

在学习过有this的编程语言中,this一般都是指向当前实例对象的,对于JavaScript来说,其实也是这样。但有时候在使用【this】时,会感觉它的行为很奇怪,不能能达到预期的效果,这往往是因为没有正确的了解【this】本身所指向的真正的实例对象所引起的。

 

在JavaScript中,【this】总是指向执行函数的调用者,或者可以说是指向拥有方法的对象。

<textarea cols="50" rows="15" name="code" class="javascript">function doSomething() { this.style.color = '#cc0000'; }</textarea> 

 

例子中,函数【doSomething】定义在页面中,所以它指向的就应该是当前页面,即全局对象【window】。但是,如果我们在页面中某个元素的属性内部使用了【this】,那么【this】指向的内容就是这个元素。如下面的例子,【this】指的就是元素【input】。

<textarea cols="50" rows="15" name="code" class="xhtml">&lt;input type="button" value="Do not touch me!" onclick="alert(this.value);" /&gt;</textarea> 

 

再看一个类定义的例子:

<textarea cols="50" rows="15" name="code" class="c-sharp">function CSDN() { this.url = "www.csdn.net"; this.author = "KNIGHTRCOM"; } CSDN.prototype.output = function() { alert(this.url + " - " + this.author); } new CSDN().output();</textarea> 

 

首先定义一个类【CSDN】,并为这个类添加一个【output】方法,output方法内使用的【this】所指向的内容,就是类【CSDN】的实例对象【new CSDN()】。也就是之前说的,【this】指向拥有方法【output】的实例对象【new CSDN()】。

 

接下来我们来学习一个重要的概念,拷贝与引用。

<textarea cols="50" rows="15" name="code" class="xhtml">&lt;mce:script type="text/javascript"&gt;&lt;!-- element.onclick = doSomething; // --&gt;&lt;/mce:script&gt; &lt;element onclick="doSomething()"&gt;</textarea> 

 

我们比较一下上面两种用法。第一种用法是将函数【doSomething】拷贝到【element】的【onclick】事件句柄中,这样【doSomething】的内容就成为元素【element】的一个方法,当该方法被执行时,【this】所指向的内容即为方法的拥有者【element】。但对于第二种用法(内联方式)来说,实际上是一种变相的调用,当【click】事件被触发时,【doSomething】确实会被调用,但并非作为元素【element】的方法来调用,所以【this】也就不会指向【element】了。

 

从代码上看,拷贝方法所执行的代码就是:

<textarea cols="50" rows="15" name="code" class="javascript">element.onclick = doSomething; alert(element.onclick) || // function doSomething() { this.style.color = '#cc0000'; }</textarea>  

 

而引用方式执行的代码是:

<textarea cols="50" rows="15" name="code" class="javascript">&lt;element onclick="doSomething()"&gt; alert(element.onclick) || // function onclick() { doSomething() }</textarea> 

 

从执行的代码中看,方法【doSomething】的拥有者并非当前元素,所以【this】的指向自然也不是当前元素了。

 

图解:

 

在内联的引用方式下,可以通过使用【document.getElementById】或【event.target】来达到使用【this】的效果,但在使用【event.target】之前,最好查阅相关的文档说明。

 

拷贝举例:

<textarea cols="50" rows="15" name="code" class="javascript">element.onclick = doSomething element.addEventListener('click',doSomething,false) element.onclick = function () {this.style.color = '#cc0000';} &lt;element onclick="this.style.color = '#cc0000';"&gt;</textarea> 

 

引用举例:

<textarea cols="50" rows="15" name="code" class="javascript">element.onclick = function () {doSomething()} element.attachEvent('onclick',doSomething) &lt;element onclick="doSomething()"&gt;</textarea> 

 

拷贝与引用的混合使用:

<textarea cols="50" rows="15" name="code" class="javascript">&lt;element onclick="doSomething(this)"&gt; function doSomething(obj) { // this is present in the event handler and is sent to the function // obj now refers to the HTML element, so we can do obj.style.color = '#cc0000'; }</textarea>