[轉] Javascript中this用法小結

1. 概述
this是面嚮對象語言中的一個重要概念,在JAVA,C#等大型語言中,this固定指向運行時的當前對象。但是在javascript中,由於 javascript的動態性(解釋執行,當然也有簡單的預編譯過程),this的指向在運行時才確定。這個特性在給我們帶來迷惑的同時也帶來了編程上的自由和靈活,結合apply(call)方法,可以使JS變得異常強大。

2.變化的this
在JavaScript中,this通常指向的是我們正在執行的函數本身,或者是指向該函數所屬的對象(運行時)。當我們在頁面中定義了函數 doSomething()的時候,它的owner是頁面,或者是JavaScript中的window對象(或 global對象)。對於一個onclick屬性,它爲它所屬的HTML元素所擁有,this應該指向該HTML元素。

2.1在幾種常見場景中this的變化

函數示例
function doSomething ()
{
alert(this.navigator); //appCodeName
this.value = "I am from the Object constructor";
this.style.backgroundColor = "# 000000";
}
1. (A)作爲普通函數直接調用時,this指向window對象.

2. (B)作爲控件事件觸發時

1) inline event registration 內聯事件註冊 .將事件直接寫在HTML代碼中(<element

οnclick=”doSomething()”>), 此時this指向 window對象 。

2) Traditional event registration 傳統事件註冊 (DHTML方式).
形如 element.onclick = doSomething; 此時this指向 element對象

3) <element οnclick=”doSomething(this)”>作爲參數傳遞可以指向element

3. (C)作爲對象使用時this指向當前對象。形如:new doSomething();
4. (D)使用apply 或者call方法時,this指向所傳遞的對象。

形如:var obj={}; doSomething.apply(obj,new Array(”nothing”); //thisobj
2.2 this 指向分析

1 A場景。
直接調用的情況下,doSomething的運行時擁有者是window對象,因此this指向window
圖示:
[img]http://www.o2sky.cn/quarters/wp-content/uploads/2007/11/clip_image001.gif[/img]
圖1:A場景

2 B場景。
1)Traditional Event Registration
當我們要讓函數中的this指向當前HTMLELEMENT時,可這樣寫
element.onclick = doSomething;
doSomething的引用(地址)賦給了element的onclick屬性(這樣就成爲了函數)。此時
doSomething運行時擁有者(owner)就變成了element,this便指向了element。

圖示:

圖2: B場景 Traditional Event Registration

進行批量添加事件時,this均可正確指向。

圖示:

圖3: 多次Traditonal Event Registration

2) Inline Event Registration
形如 <element οnclick=”doSomething()”>
圖示:

圖4:B場景 Inline Event Registration

這兩種註冊方式的區別是
element.onclick = doSomething;
alert(element.onclick)
可以得到
function doSomething() {
alert(this.navigator); //appCodeName
this.value = "I am from the Object constructor";
this.style.backgroundColor = "# 000000";
}
可以看到this關鍵字被展現在onclick函數中,它指向HTML元素。

如果執行
<element οnclick="doSomething()">
al ert(element.onclick)

可以得到 :
function onclick(){
doSomething();
}

這僅僅是對doSomething()函數的一次調用,而doShomething的擁有者是window,因此 doSomething內的this指向window對象(囉嗦哦…….).

3 . C場景
具體內部細節不太瞭解,不知道是否可以這樣理解
new doSomething(…..)
約等同於
var tempObj = {}; doSomething.apply(obj,new Array());
這樣tempObj 可以得到doSomething內所定義的屬性和方法,但是對 於 doSomething.prototype上的屬性方法無法得到-_-!!

4 D場景
不懂…..

完了
不專業,比較淺顯,想不出幾個專有名詞,鬱悶~

PS 1:好多內容是copy的(*_*!),對圖中表達有點疑意。圖上多次寫出 copy of function ,按照字面理解是函數對象的拷貝,我認爲實際上是一個引用拷貝,對象拷貝是不可能的,如果是這樣的話,每次添加事件都會拷貝一次對象,這顯然不妥。

PS 2: 因爲this指向在運行時才確定,我們經常碰到一個問題,當給一個DOM對象添加事件後,我們希望this指向一個指定對象,而非DOM對象本身,如下例。
<input type="button" id='btn' />
<script language="javascript">function btnObj(id)
{
this.disabled = true;
this.btn=document.getElementById(id);
/*
this.btn.onclick = btnOnclick ;
假如我們這樣寫,this會指向DOM對象,btnOnclick執行過程會報錯
因爲DOM btn並沒有一個btn屬性
*/
//通過這種方式可以解決這個問題[有些情況也可用tempThis = this這種形式]
this.btn.onclick = passHandler(this,btnOnclick);}function btnOnclick()
{

//如果this是DOM對象,這裏就會報錯,因爲沒有btn屬性
this.btn.disabled = this.disabled;
}

function passHandler(obj,fun,arg)
{
return function(){
//if(!arg) {var arg = [];}
return fun.apply(obj,(arg?arg:[]));
}
}

new btnObj(”btn”);
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章