this 是物件導向語言裡很重要的觀念與應用,像是 Java, PHP 等等。而自己第一次聽到這名詞是大學時學習 Java 的時候,後來接觸 php 時也又碰到了 this,但對 this 到底為何其實都不是很懂,被困擾了很久,單看 this 字面的意思還是讓人覺得抽象,不過當時也有不少同學對於 this 也都是一知半解,但寫程式的時候還是會知道該怎麼使用它,個人覺得這不是個好的現象,所以今天來分享一下對 this 的學習心得,並主要以 javascript 作為範例。
什麼是 this
?
this 代表當前的物件,更直白的說就是正在使用的物件為何,我們會用 this 來代表,這是很重要的一點。一般而言會呼叫 this 的場合僅在 method 裡面使用,而 this 代表的對象就是函式所屬的物件
1 | var zilla = { |
this 如何決定?
this的值是由環境
執行期間
決定,所以要看呼叫該方法時的環境決定,屬於 window(全域範圍)或某特定物件:
1 | var name = "Windows\'s Godzilla"; |
當方法裡面包覆方法時,this 會指向全域物件
當物件裡面含有巢狀方法時(方法裡面又包裹方法),則 this 會迷失方向,因此不會參考該物件,轉而參考全域物件,也就是 window 物件
1 | name = "Window Godzilla" |
即使傳入一個匿名方法,而該方法裡面又有呼叫到 this 時,依然會轉而參考 window 物件
1 | name = "Window Object" |
如果怕 this 迷失的話,我們可以明確指定給它
有很多方法可以避免 this 值迷失,常見的有下列幾種
1. 依靠範圍練尋找,把 this 指定給明確變數
1 | var myObject = { |
2. 使用 call 方法來明確指定使用哪個物件當做 this
1 | name = "Window Name" |
3. 使用 apply 方法來明確指定使用哪個物件當做 this
1 | name = "Window Name" |
使用 new 來建立函式時,this 會參考到該 new 出來的 instance
聽來有點饒舌,但大概就是這樣的意思,此舉用法上很接近其他 oop 的實體變數的感覺,直接看範例
1 | var Godzilla = function() { |
若不使用 new 的話,則規則同一般使用方式
在 prototype 裡使用 this ,則會參考到該建構式的 instance
如果說前一則提到的觀念像是使用實體變數的感覺,這邊則像是實體方法裡使用到實體變數的概念,因為定義在 Object.prototype 裡的方法可以被共享,之後該 Object 的實例共享,所以我們可以把它看做是實體方法,裡面呼叫的 this 則自然是參考到該實體的變數囉:
1 | var Godzilla = function() { |
結論
其實 this 觀念並沒有這麼難懂,且大多數 oop 的 this 觀念大略是相同的,都是在幫我們釐清我們當前使用或定義的對象為何罷了。只是可能依語言特性而個有些用法上的差異等等,例如 ruby 裡是用 self 幾乎等同 this 的;以 js 為範例介紹,是因 js 上物件的表達方式比較多變,所以 this 的變化也就更多元,較容易搞混,但懂得原理,只要稍微停下來思考相信很快就在也不會被難倒了,或搞混了,
千萬不要迷失自我為何啊。
以上若有錯誤或其他建議都歡迎告知或討論唷,感謝^^