轉載javascript
項目實踐倉庫java
https://github.com/durban89/typescript_demo.git tag: 1.2.4
爲了保證後面的學習演示須要安裝下ts-node,這樣後面的每一個操做都能直接運行看到輸出的結果。node
npm install -D ts-node
後面本身在練習的時候能夠這樣使用git
npx ts-node 腳本路徑
學習如何在JavaScript里正確使用this就比如一場成年禮。 因爲TypeScript是JavaScript的超集,TypeScript程序員也須要弄清 this工做機制而且當有bug的時候可以找出錯誤所在。 幸運的是,TypeScript能通知你錯誤地使用了 this的地方。 若是你想了解JavaScript裏的 this是如何工做的,那麼首先閱讀Yehuda Katz寫的Understanding JavaScript Function Invocation and "this"。 Yehuda的文章詳細的闡述了 this的內部工做原理,所以這裏只作簡單介紹。程序員
繼續上篇文章【TypeScript基礎入門 - 函數 - this(二)】github
咱們也看到過在回調函數裏this報錯的狀況,當你將一個函數傳遞到某個庫函數裏稍後會被調用時。 由於當回調被調用的時候,它們會被當成一個普通函數調用, this將爲undefined。 稍作改動,你就能夠經過 this參數來避免錯誤。 首先,庫函數的做者要指定 this的類型,以下實例typescript
interface UIElement { addClickListener(onclick: (this: void, e: Event) => void): void; }
this: void表示addClickListener指望onclick是一個不須要此類型的函數。
其次,用這個註釋你的調用代碼,以下所示npm
interface UIElement { addClickListener(onclick: (this: void, e: Error) => void): void; } class Handler { info: string; onClickBad(this: Handler, e: Error) { // oops, used this here. using this callback would crash at runtime this.info = e.message; } } let h = new Handler(); let uiElement: UIElement = { addClickListener(onclick: (this: void, e: Error) => void) { // do something } }; uiElement.addClickListener(h.onClickBad); // 這裏會報錯
指定了this類型後,顯式聲明onClickBad必須在Handler的實例上調用。 而後TypeScript會檢測到 addClickListener要求函數帶有this: void。 咱們添加另一個函數作下對比,以下函數
interface UIElement { addClickListener(onclick: (this: void, e: Error) => void): void; } class Handler { info: string; onClickBad(this: Handler, e: Error) { this.info = e.message; } onClickGood(this: void, e: Error) { console.log('點擊了!'); } } let h = new Handler(); let uiElement: UIElement = { addClickListener(onclick: (this: void, e: Error) => void) { // do something } }; uiElement.addClickListener(h.onClickGood);
經過將h.onClickBad更換爲h.onClickGood,就能正常調用。
由於onClickGood指定了this類型爲void,所以傳遞addClickListener是合法的。 固然了,這也意味着不能使用 this.info. 若是你二者都想要,你不得不使用箭頭函數了,以下oop
interface UIElement { addClickListener(onclick: (this: void, e: Error) => void): void; } class Handler { info: string; onClickGood = (e: Error) => { this.info = e.message } } let h = new Handler(); let uiElement: UIElement = { addClickListener(onclick: (this: void, e: Error) => void) { // do something } }; uiElement.addClickListener(h.onClickGood);
這是可行的由於箭頭函數不會捕獲this,因此你老是能夠把它們傳給指望this: void的函數。 缺點是每一個 Handler對象都會建立一個箭頭函數。 另外一方面,方法只會被建立一次,添加到 Handler的原型鏈上。 它們在不一樣 Handler對象間是共享的。
本實例結束實踐項目地址
https://github.com/durban89/typescript_demo.git tag: 1.2.5