Welcome 微信登录

首页 / 脚本样式 / JavaScript / PPK 谈 JavaScript 的 this 关键字 [翻译]

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

自己本身

先来看看函数 doSomething() 里的 this 到底是指向(refer to)了什么?

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

JavaScript的 this 总指向所运行的函数“自己本身”。也就是说,它是一种指向函数对象的方法。在页面中定义 doSomething() 函数,自己本身是指页面。也就是说,是指 JavaScript 的 window 对象(全局对象)。而 onclick 属性它自己本身是属 HTML 元素所有。

这个“所有权”是 JavaScript 的 OO(面向对象)特性的后果。在 把对象作关联数组 页面中有更多信息。

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

如果 doSomething() 运行时没有任何与之预留相关的话,关键字 this 指向 window(窗口) ,该函数将会改动 window 的 style.color。而 window 没有 style 这样的对象,所以该函数会引发 JavaScript 的错误。

拷贝(copying)

因此,用好 this 有些难度。像在函数中使用的上面例子的这种情况,它应该指向 HTML 元素“自己本身”。换个说法是,有个函数拷贝指向 onclick 属性。 我们来看看在传统事件注册中的情况。

element.onclick = doSomething;

因为函数拷贝全指向了 onclick 属性(现在变成了方法),所以在事件处理执行时,this 指向 HTML 元素并将 color 改动。

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

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

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

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

指向(referring)

要是用 行内事件注册呢?

<element onclick="doSomething()">

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

doSomething();

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

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

不一样?

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

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

得到的是

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

可以看到,this 关键字在 onclick 方法中。它指向 HTML 元素。

但是如果这么做:

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

得到的是

function onclick(){doSomething()}

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

例子-拷贝

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

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

例子-指向

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

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

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

结合

使用行内事件注册时,也可以把 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 doobj.style.color = "#cc0000";}