TS學習筆記(四):函式
函式是 JavaScript 應用程式的基礎。 它幫助你實現抽象層,模擬類,資訊隱藏和模組。 在 TypeScript 裡,雖然已經支援類,名稱空間和模組,但函式仍然是主要的定義行為 的地方。 TypeScript 為 JavaScript 函式添加了額外的功能,讓你可以更容易地使用。
為函式定義型別
一般使用中,我們可以不必完整寫出函式型別 ,因為 TypeScript 會為我們自動推斷出型別,需要注意的是:型別中的引數名稱可以不必和值中的引數名稱匹配,只要它們型別是相容的便可。
// 書寫完成函式型別 let square: (x: number, y: number) => number; square = function (width: number, height: number): number { return width * height; } console.log(square(5, 6)); // 30 複製程式碼
可選引數
引數名後面接一個? ,該引數便成為了可選引數,需要注意是:可選引數必須跟在必須引數後面
let square: (x: number, y: number, s?: number) => number; square = function (width: number, height: number, scale?: number): number { if(scale) { return width * height * scale; } else { return width * height; } } console.log(square(5, 6)); // 30 console.log(square(5, 6, 2)); // 60 複製程式碼
預設引數
當用戶沒有給一個引數傳遞值或者傳遞的值是 undefined 時,這個引數叫做可以有預設值的引數,我們可以使用= 指定這種情況下的取值,在所有的必須引數後面帶預設值的引數都是可選的,與可選引數一樣,在呼叫函式的時候是可以省略的,但是有預設值的引數不一定要放在必須引數的後面,也可以放在前面,當傳入 undefined 的時候,就會取預設引數指定的預設值。
function square(width = 6, height = 6, scale: number, cut = 10): number { return width * height * scale - cut; } square(5, undefined, 2); // 5 * 6 * 2 - 10 = 50 複製程式碼
剩餘引數
與 ES6 一樣,TypeScript 也支援剩餘引數。
function max(a: number, b: number, ...resArr: number[]): number { return Math.max(a, b, ...resArr); } console.log(max(10, 5, 6, 100, 200)); // 200 複製程式碼
this 問題
在 TypeScript 中,可以在第一個引數裡指定 this 的型別,雖然 this 在方法第一個引數的位置,但是它的作用實際上只是限定 this 的型別,並不是讓我們作為第一個引數傳值
class Person { constructor(public name: string, public age: number) { } show(this: Person, doing: string) { console.log(`${this.name} is ${this.age}, now is ${doing}`); } } let me = new Person('funlee', 18); me.show('Coding'); // funlee is 18, now is Coding 複製程式碼
可以對回撥函式裡的 this 型別做限定:
interface UIElement { addClickListener(onclick: (this: void, e: Event) => void): void } 複製程式碼
其中,this: void 表示 addClickListener 期望 onclick 回撥函式不需要指定 this 的型別。那麼限定了 this 型別後,會有什麼效果呢?看如下例子:
class Handler { info: string; onClickBad(this: Handler, e: Event) { this.info = e.message; } } const h = new Handler(); uiElement.addClickListener(h.onClickBad); // 報錯,因為this型別不匹配 // 修復報錯:變更this型別 class Handler { info: string; onClickBad(this: void, e: Event) { this.info = e.message; } } const h = new Handler(); uiElement.addClickListener(h.onClickBad); 複製程式碼
過載
TypeScript 允許我們定義多個函式型別定義來進行函式過載,編譯器會根據定義列表去處理函式的呼叫。
function foo(x: number): string function foo(x: string): string function foo(x): any { if (typeof x === 'number') { return `${x} is a number`; } else if (typeof x === 'string') { return `${x} is a string`; } } console.log(foo(123)); // 輸出:123 is a number console.log(foo('123')); // 輸出:'123' is a string 複製程式碼