JavaScript心經-this关键字篇

this关键字

this關鍵字在JavaScript裡的具體含義完全不同於C#或者Java這種基於類的編程語言,所以參考後者來理解前者只會更加迷惑。在JavaScript裡並不存在C#中的類,也就不存在類的實例,所以this不可能指向那樣一個東西。


JavaScript裡的this究竟該怎樣解釋,目前我還沒有發現任何術語可以簡單地說明並且不具歧義性,很多人把它稱為函數執行時的上下文(context),但是JS的術語裡context其實是用來指JS引擎給被調用函數維護的一組數據,這個context本身不是對JS代碼可見的,是引擎內部的實現,this所指向的內容則是這組數據裡包含的一個項目,從最廣義的角度解讀context的話,要把this說成是執行函數的上下文也依然不夠嚴格,我覺得它也只能是其中的一部分,所以我只能說它指向著一個特定的函數的上下文,如果沒有它的話,想引用這個上下文裡的屬性確實有點難度。


this到底指向什麼,要取決於該函數是怎麼被調用的(基本上跟它如何被定義的關係不大),在不同的調用情況裡,對this進行的綁定方法有所不同,這種綁定是動態的,完全在函數被調用時才決定的。那麼現在來盤點下在JavaScript裡,函數究竟有哪些被調用的方式:

  • 作為一個獨立的函數被調用,不論是在全局作用域裡,或者在局域作用域裡。
  • 被作為一個對象的方法被調用。
  • 作為一個事件的處理函數被綁定在該事件上(比如通過addEventListener),當該事件觸發時被自動調用。
  • 作為回調函數,以參數的形式傳給其他函數(比如setTimeout),再被調用。
  • 通過apply或者call函數被調用。
  • 作為“構造函數”,放在new關鍵字後面被調用。


作為一個獨立的函數被調用(stand alone)



上面的截圖裡展示的是最基本的情況,做一點微弱的變動,它可以有不同的形式:





其實這個調用模式只是下一個將要講到的調用模式的一種特例,之後會再回來說這個問題。


作為一個對象的方法被調用(member method)

在JavaScript裡,並沒有真正意義上的“類,”面向對象的機制是通過叫“原型鏈”的東西實現的,所以在JS裡,你可以給一個對象定義成員方法的方式就有很多種,而且也很靈活。從編碼風格來看,你常見到的會有下面幾種(實際上並不僅限於這幾種方法):







在上面這三個例子裡,freud函數都是以lacan對象的方法被調用的,所以輸出的dream是lacan對象內的那個成員屬性,而不是全局作用域那個。


作為一個事件的處理函數(handler)

從這裡開始,演示代碼要變複雜一些。為了簡化問題,我使用HTML5裡的一個新功能:標籤裡的自定義屬性(custom attribute)。先有如下html代碼:

<!DOCTYPE html>

<HEAD>

<TITLE></TITLE>

<SCRIPT src="this-explicit-binding-1.js"></SCRIPT>

</HEAD>


<BODY>
	<button id="lacan" data-dream="sleep protector">Try this</button>
</BODY>

</HTML>


有一個簡單的按鈕,給它一個id這樣JS就可以在DOM樹裡訪問到它,然後再添加一個data-*屬性,這樣就可以在JS裡通過dataset屬性訪問這些自定義的標籤屬性。我要展示的問題是在JS裡給按鈕lacan綁定一個處理點擊事件的函數,當lacan被點擊,這個函數執行時,函數內的this其實是指向lacan按鈕對象本身的。

var jung;

var dream = 'supernatural communication';

window.onload = function() {

	jung = document.getElementById("lacan");

	jung.addEventListener("click", function(){
	    console.log(this.dataset.dream);
	});

};


Note: 如果直接把var jung = document.getElementById("lacan");寫在window.onload外面是不行的,因為在它被執行的時候,整個HTML頁面還沒有被加載完成,DOM樹沒有被生成,所以jung將會是null。


Ref:
http://stackoverflow.com/questions/588040/window-onload-vs-document-onload/28144681
https://developer.mozilla.org/en/docs/Web/Guide/HTML/Using_data_attributes
http://www.w3schools.com/tags/att_global_data.asp
http://www.w3schools.com/jsref/met_element_addeventlistener.asp





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值