简明现代魔法 -> JavaScript -> 谈 JavaScript 的 this 关键字

谈 JavaScript 的 this 关键字

2010-04-04

One of the most powerful JavaScript keywords is this. Unfortunately it is hard to use if you don't exactly know how it works.

在 JavaScript 中 this 是最重要的关键字之一。这篇贴文就是要告诉你如何用好 this。

Below I explain how to use it in event handling. Later on I'll add some information about other uses of this.

下面我先讲如何在event handling(事件处理)中用它,然后再讲 this 的其他用法。

Owner 所有者

The question that we'll discuss for the remainder of the page is: What does this refer to in the function doSomething()?

先来看看在函数 doSomething() 中 this 究竟指向(refer to)什么?

function doSomething() {
   this.style.color = '#cc0000';
}

In JavaScript this always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of. When we define our faithful function doSomething() in a page, its owner is the page, or rather, the window object (or global object) of JavaScript. An onclick property, though, is owned by the HTML element it belongs to.

JavaScript 中的 this 总是指向正执行的函数的所有者。或者是说,它是指向函数这个对象的一种手法。在页面中定义函数 doSomething() 的时候,它的所有者是这个页面。更确切的说是 JavaScript 的 window 对象(全局对象)。而 onclick 属性归属 HTML 元素所有。

This "ownership" is the result of JavaScript's object oriented approach. See the Objects as associative arrays page for some more information.

这种归属谁所有的关系是 JavaScript 的 OO(面向对象)特性导致的。更多信息详见 把对象作关联数组。

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          --------------------                          |
|          | onclick property |                          |
|          --------------------                          |
|                                                        |
----------------------------------------------------------

If we execute doSomething() without any more preparation the this keyword refers to the window and the function tries to change the style.color of the window. Since the window doesn't have a style object the function fails miserably and produces JavaScript errors.

这里在 doSomething() 执行时,关键字 this 指向 window(窗口) ,该函数将会改动 window 的 style.color。而 window 没有 style 这个对象,所以该函数会引发 JavaScript 的错误。

Copying

So if we want to use this to its full extent we have to take care that the function that uses it is "owned" by the correct HTML element. In other words, we have to copy the function to our onclick property. Traditional event registration takes care of it.

因此,想要用好 this 就请继续往下看。像前面的例子在函数中使用的这种情况,this 指向它归属谁所有的那个 HTML 元素。也就是说,有个函数拷贝指向 onclick 属性。 我们来看看在传统事件注册中的情况。

element.onclick = doSomething;

The function is copied in its entirety to the onclick property (which now becomes a method). So if the event handler is executed this refers to the HTML element and its color is changed.

函数是它整个的拷贝,指向 onclick 属性(现在变成了方法)。因此,事件处理被执行时,this 指向 HTML 元素并将改动 color。

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

The trick is of course that we can copy the function to several event handlers. Each time this will refer to the correct HTML element:

这样我们可以拷贝函数给多个事件处理。每次 this 将指向正确的 HTML 元素:

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------          |            |
|                                           |            |
|   -----------------------                 |            |
|   | another HTML element| <-- this        |            |
|   -----------------------     |           |            |
|               |               |           |            |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

Thus you use this to the fullest extent. Each time the function is called, this refers to the HTML element that is currently handling the event, the HTML element that "owns" the copy of doSomething().

每次函数被调用,this 指向当前所处理的事件的那个 HTML 元素( doSomething() 的拷贝“所有”)。

Referring 指向

However, if you use inline event registration

要是用 行内事件注册呢?

<element onclick="doSomething()">

you do not copy the function! Instead, you refer to it, and the difference is crucial. The onclick property does not contain the actual function, but merely a function call:

这里没有拷贝函数,而是指向它,有什么不一样呢? 这个 onclick 属性没有包含实际函数,而只是一个函数调用。

doSomething();

So it says “Go to doSomething() and execute it.” When we arrive at doSomething() the this keyword once again refers to the global window object and the function returns error messages.

上面的意思是:“到 doSomething() 那里去执行它”。在doSomething()里面,this 关键字再次指向全局 window 对象,那么函数会返回错误的消息。

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------         / \           |
|          | go to doSomething() |          |            |
|          | and execute it      | ---- reference to     |
|          -----------------------       function        |
|                                                        |
----------------------------------------------------------

The difference 不一样?

If you want to use this for accessing the HTML element that is handling the event, you must make sure that the this keyword is actually written into the onclick property. Only in that case does it refer to the HTML element the event handler is registered to. So if you do

如果是用 this 去访问 HTML 元素来处理事件的话,那么必须肯定它实际是写入了 onclick 属性中。就算它指向 HTML 元素的事件处理是已注册。如果这么做:

element.onclick = doSomething;
alert(element.onclick)

you get

function doSomething()
{
	this.style.color = '#cc0000';
}

As you can see, the this keyword is present in the onclick method. Therefore it refers to the HTML element. But if you do

可以看到,this 关键字在 onclick 方法中。它指向 HTML 元素。 但是如果这么做:

<element onclick="doSomething()">
alert(element.onclick)

you get

function onclick()
{
	doSomething()
}

This is merely a reference to function doSomething(). The this keyword is not present in the onclick method so it doesn't refer to the HTML element.

这里只是指向函数 doSomething()。this 关键字不在 onclick 方法中。它没有指向 HTML 元素。

Examples - copying

this is written into the onclick method in the following cases:

在下面示例中,this 写入 onclick 方法中:

element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
<element onclick="this.style.color = '#cc0000';">

Examples - referring

In the following cases this refers to the window:

在下面示例中,this 指向 window:

element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
<element onclick="doSomething()">

Note the presence of attachEvent(). The main drawback of the Microsoft event registration model is that attachEvent() creates a reference to the function and does not copy it. Therefore it is sometimes impossible to know which HTML currently handles the event.

要注意上面的 attachEvent。它的缺点是微软事件注册模型,它创建了到该函数的指向,而且没有拷贝它。所以有时不可能弄清楚 HTML 当前的处理事件是哪个。

Combination 结合

When using inline event registration you can also send this to the function so that you can still use it:

使用行内事件注册时,也可以把 this 发送给函数。所以可以这么用:

<element onclick="doSomething(this)">

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';
}
随机文章推荐
网站分类


注:如需转载本文,请注明出处(原文链接),谢谢。更多精彩内容,请进入简明现代魔法首页。

进入新博客
喜欢本文,就分享它吧
给我留言
您的名字:
您的邮件:
您的网站:


 

copyright © 2009 简明现代魔法    学习、分享、进步

power by Gonn 感谢所有关心和支持本站的朋友们