Javascript 在不同函式定義方式中使用 this
前言
在使用物件導向程式設計時,一定會碰到this
(在python裡是self
)
要百分之百了解this
的作用原理其實談不上容易,但簡單來說:
在一個 class 中呼叫
this
時,this
指的是那個 class 本身
或是更 general 一點:
誰呼叫到
this
,this
就是誰
但最近遇到一個情形,呼叫this的時候找不到理應存在的變數
情形
這是一個 IconDisplayer 物件
調用 display() method,回傳 <Image>
1 | const IconDisplayer = { |
運行時他會告訴你:
TypeError: Cannot read property ‘Current’ of undefined
意思就是說,程式找不到 Current 這個變數
但是很奇怪,明明就定義在物件裡R,也用了this
應該找得到才對呀
原因
後來查了一下發現一切都是 arrow function 的緣故
MDN & W3Schools:
- In arrow functions, this retains the value of
the enclosing lexical context’s this. - Arrow functions do not have their own this.
- In global code, it will be set to the global object.
- In arrow functions, this retains the value of
如果是呼叫以前的傳統函數,每次都會建立一個環境 (Function Execution Context)來運行,並把當時的呼叫者令為this,誰呼叫 誰就是this
但定義 arrow function 時不會有這個流程
因此在其中使用this時,指的便會是外層所使用的 global this,在 HTML 裡就是 window
例如上述的例子:我們只要把this改成IconDisplayer就可以了
1 | display: () => { |
不然就要用傳統函式:
display: function(){
if (currency === 'USD') { return (this.Current.USD) }
}
結語
曾經看到有人說應該要把 arrow function 視為獨立的新語法,而不是傳統function 的變化,因為有時運作方式是截然不同,今天更能體會到這點了!
最後,今天的重點:
this 的值只跟「你如何呼叫、誰呼叫」有關,與程式碼位於哪裡完全無關
參考:iT邦幫忙