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/