JavaScript的this是個奇妙的東西,我歷經了一段學習與摸索才有較清楚的觀念。最近在寫TypeScript,踩到一個關於this的小陷阱,特分享兼備忘。

用以下的class舉例:

在類別中宣告了parseResult()函式,另外有個getResultByAjax()函式,透過jQuery.post()呼叫取得資料後打算以parseResult()解析。在Boo class內部要呼叫自身函式,直覺會寫成this.parseResult(),TypeScript為強型別,編輯器沒傳出錯誤,也能順利編譯成功,代表程式沒有問題?

仔細想想,錯得離譜!

在$.post()的結果處理函式裡this不會指向Boo的Instance,需使用Closure傳進去。平時在撰寫JavaScript時,已經養成習慣會注意這些細節;到了TypeScript,以為有強型別保護就高枕無憂,精神一鬆懈,搞出這種低級錯誤!

其實,若更仔細一點也能發現玄機:

被包在function() { }中的this,一律被視為any,加上任何方法、屬性都可成功編譯,而且在輸入parseResult時不會有Intellisense提示,出現這些徵兆時就該有所警覺。

解決方法一如在JavaScript的解法,宣告self變數指向this,在結果函式裡改用self就成了。如此,編輯時會看到Intellisense帶出提示,就代表寫法正確囉! (有更簡潔的做法,請再看下去)

【2014-07-18更新】

文章登出後馬上接到多方回饋,只需改用Lambda寫函式,TypeScript就會自動處理this問題,不需要苦情自幹。例如以下範例:

感謝網友 Kevin、Kevin YangHihi Huang 熱心回饋!


Comments

# by Kevin

在typescript裡面,如果類似這種情形,我都會這樣子處理 functionName(value:any){ /// some code } $http.get('url',(value)=>{ this.functionName(value); }); 這時的this就會指到同一個class裡面的function

# by Jeffrey

to Kevin, 謝謝分享,已加入本文。

# by Phoenix

原來是這樣,我被搞的情境剛好相反,本來以為會是function的this結果變_this,最後還用class的寫法弄好久才完成功能

# by Jeffrey

to Phoenix,對耶,TypeScript好心幫忙,但在真正想用this的函式場合還真的會有反效果。謝謝你的經驗分享。

# by 冷凍蝦米

黑暗大....方便把你這篇的連結加入到此篇文章嗎? http://blog.darkthread.net/post-2014-09-18-this-in-typescript-again.aspx 讓讀者可以知道使用時機 :) ?

# by Jeffrey

to 冷凍蝦米, 其實本來就有加在this關鍵字上,但引導效果顯然不好,謝謝你的建議,已再補強。

Post a comment