TypeScript的this偵錯陷阱

接獲同事報案追查TypeScript問題,二人一起陷入迷霧近20分鐘才恍然大悟…

有段TypeScript程式自訂類別,在類別方法用this.PropName="..."修改自身屬性值(註:類似需求我習慣用self大法,寫成self.PropName="…"),偵錯時用瀏覽器F12開發者工具下指令檢查,卻發現this.PropName沒有被正確設定,我建議在程式碼加入console.log(this.PropName)交叉檢查,跑出更詭異的狀況,如下圖:

程式碼中的console.log(this.Name)得到"Jeffrey",在F12 Console下指令查this.Name卻得到undefined,WTF?

百思不得其解,許久之後才猛然想起-TypeScript的this語法糖!遇到類別方法內出現this,會偷偷將this換成_this,幫開發者節省另外宣告self、that形成Closure的麻煩。

留意上圖顯示的程式碼檔案是lab.ts而非lab.js,這是瀏覽器的德政,透過lab.js.map讓開發人員能用TypeScript原始碼偵錯,比使用編譯過的JavaScript更接近原本的演算法及程式邏輯。

開啟lab.js後真相大白。TypeScript Test()方法裡用的this,實際上已被TypeScript換成_this,永遠指向類別的Instance;而在setTimeout觸發函式的當下,從F12 Console下指令所存取的this則是DOM window,而非Player Instance,要改用_this.Name才對,TypeScript裡的this.Name有魔法加持,參考它拿來F12 Console測試,馬車變南瓜。之前幾乎都用self處理,一時不察便中招。

佛心的TypeScript為this加上魔法,貼心的瀏覽器提供TypeScript偵錯,粗心的開發者卻因此鬼打牆…

看完以上說明,一下this是Player,一下this是window,被搞得好亂,對吧?這也是我不愛TypeScript this魔法,寧可傻傻自己宣告self的理由。頭腦清楚時,還能記得this其實是_this,等那天射茶包射到天昏地暗或疲勞駕駛,難保不會再次跌坑。

評估之後,還是自己宣告self比較好。

【延伸閱讀】

歡迎推文分享:
Published 23 April 2016 09:28 AM 由 Jeffrey
Filed under:
Views: 4,853



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<April 2016>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication