JavaScript最有魔力的关键字之一就是this。但很不幸它并不容易驾驭。我会先来解释如何在事件句柄中使用this。稍后我会提及一些关于this的其他用法。
拥有者(Owner)
function doSomething() {
this.style.color = "#cc0000";
}
在JavaScript中this永远指向函数执行时的拥有者(owner), 更确切地说,是指向了这个方法所属的对象。 当我们在页面中定义了doSomething()函数,
他的拥有者就是window object (or global object) of JavaScript。 然而onclick 属性则是属于它对应的html element。
------------ window --------------------------------------
| / \ |
| | |
| this |
| ---------------- |
| | HTML element | <-- this ----------------- |
| ---------------- | | doSomething() | |
| | | ----------------- |
| -------------------- |
| | onclick property | |
| -------------------- |
| |
-----------------------------------------------------------
如果我们没有更改拥有者而直接执行doSomething函数,那么它将试图更改window的style对象而最终报错。
复制引用(Copying)
element.onclick = doSomething;
所以当函数执行时将会改变html元素的color。
------------ window --------------------------------------
| |
| |
| |
| ---------------- |
| | HTML element | <-- this ----------------- |
| ---------------- | | doSomething() | |
| | | ----------------- |
| ----------------------- | |
| |copy of doSomething()| <-- copy function |
| ----------------------- |
| |
----------------------------------------------------------
这种技巧当然适用于把函数复制到多个不同元素的事件处理函数上。每次执行,this都指向不同的元素。
------------ window --------------------------------------
| |
| |
| |
| ---------------- |
| | HTML element | <-- this ----------------- |
| ---------------- | | doSomething() | |
| | | ----------------- |
| ----------------------- | |
| |copy of doSomething()| <-- copy function |
| ----------------------- | |
| | |
| ----------------------- | |
| | another HTML element| <-- this | |
| ----------------------- | | |
| | | | |
| ----------------------- | |
| |copy of doSomething()| <-- copy function |
| ----------------------- |
| |
----------------------------------------------------------
引用调用(Referring)
然而当你使用如下的行内注册事件方式
<element οnclick="doSomething()">
你没有复制这个函数! Instead, you refer to it, 这之间的不同非常严重。 元素的onclick
属性没有代替为实际的函数,而是仅仅调用了函数:
doSomething();
所以当执行 doSomething(),
this再次
global window object,并且会返回错误信息.
------------ window --------------------------------------
| / \ |
| | |
| this |
| ---------------- | |
| | HTML element | <-- this ----------------- |
| ---------------- | | doSomething() | |
| | | ----------------- |
| ----------------------- / \ |
| | go to doSomething() | | |
| | and execute it | ---- reference to |
| ----------------------- function |
| |
----------------------------------------------------------
The difference
如果你想执行函数时this指向正确的html元素,你必须确保 this
被写入到了元素的 onclick
属性。所以
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.
如果你这样做了:
<element οnclick="doSomething()">
alert(element.onclick)
you get
function onclick()
{
doSomething()
}
这样仅仅调用了函数doSomething()。This现在不在onclick方法里面,所以它不会指向
正确的html元素。
Examples - copying
this
is written into the onclick
method in the following cases:
element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
<element οnclick="this.style.color = '#cc0000';">
Examples - referring
In the following cases this
refers to the window:
element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
<element οnclick="doSomething()">
要注意微软的实现attachEvent()
. The main drawback of the Microsoft event registration model is thatattachEvent()
creates a reference to the function and does not copy it. Therefore it is sometimes impossible to know which HTML currently handles the event.
Combination
When using inline event registration you can also send this
to the function so that you can still use it:
<element οnclick="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';
}
转自:http://zmike86.blog.163.com/blog/static/17186042120121202122793/