TypeScript 學習系列 | 函式推斷與類(class)的方法

Function 函式

在參數位置定義參數類別,返回值則是在括號後方加上冒號及其型別,可選參數可被放在參數最後一個。

1
2
3
4
5
6
7
8
9
10
11
// 函式宣告式
function add(x: number, y: number, z?: number): number {
// 可選參數必須被放在最後一個
if (typeof z === 'number') {
return x + y + z
} else {
return x + y
}
}

let result = add(2, 3, 5)

也可以把參數 z 寫成這樣子:
z = 10,默認 z 為 number 的寫法(ES6)

1
2
3
4
5
6
7
8
9
10
11
// 函式宣告式
function add(x: number, y: number, z: number = 10): number {

if (typeof z === 'number') {
return x + y + z
} else {
return x + y
}
}

let result = add(2, 3, 5)

寫成函示表達式的話就是這樣子:

1
2
3
4
5
6
7
8
9

const add = function (x: number, y: number, z: number = 10): number {
if (typeof z === 'number') {
return x + y + z
} else {
return x + y
}
}

把滑鼠移到變數 add 上看,TypeScript 會默認成函式類型,想要賦值成其他類型會報錯
example
example

要將變數定義為函式類別,寫法如下,注意箭頭為 TS 返回聲明函數的值的方法,不是箭頭函示的箭頭~

1
const add2: (x: number, y: number, z?: number) => number = add

Tips: 直接在 node 環境上看 TS 檔案 console 結果的方法

npm install -g ts-node 

執行只要打這樣,xxxx 是你的檔案

ts-node xxxx.ts

Class 類

接下來會講到 class 父類別和子類別的方法,如果有學過 Java OOP 概念的人,在這部分應該會理解比較快,主要是其中最重要的三個觀念:封裝、繼承、多形。

封裝主要是不讓外部直接取得變數,但可以透過內部方法調用取得值。繼承的話,子類別可以從父類別取得其屬性和方法,也可以加上自己的屬性或方法覆寫。多形可以想像成繼承的方法,其本質不一樣,例如動物會叫,叫的聲音卻不一樣,透過多形的寫法,繼承父類別叫的方法,在子類別中 overriding(覆寫) 可以執行獲得不同的叫聲。

1
2
3
4
5
6
7
8
9
10
11
12
// 先做出一個動物的 class

class Animal {
name: string;
constructor(name: string) {
this.name = name
}
run() {
return `${this.name} is running`
}
}

接著利用動物這個類別創造出物件,比如熊🐻,父類別裡面有 run 這個方法,子類別可以繼承並且使用。

1
2
3
const bear = new Animal('Winne')
console.log(bear())
// Winne is running

前面提到子類別可以自行增加方法,使用 extends 表示繼承 Animal 這個 class,下面的範例是創造出狗🐶的物件當例子,並且自行加上 bark 這個方法。

1
2
3
4
5
6
7
8
9
10
11

class Dog extends Animal {
bark() {
return `${this.name} is barking`
}
}

const baobao = new Dog('baobao')
console.log(baobao.run()) // baobao.run is running
console.log(baobao.bark()) // baobao.run is barking

前面有提到,雖然動物都會叫,可是叫聲可能會不一樣,接下來要提到多形(polymorphism)的概念和方法。在貓咪類別中利用父類別的 run 方法,加上子類別自己特別的行為。允許在程式上只要制定好一個類別,能使用來操作不同物件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Cat extends Animal {
// 指到父類別的變數,需要使用 super
constructor(name) {
super(name)
}

// overriding 貓咪叫聲
run() {
return 'Meow, ' + super.run()
}
}

const maomao = new Cat('maomao')
console.log(maomao.run())
//Meow, maomao is running

Class 修飾符

修飾符包含:public, private, protected, readonly。使用修飾符是為了對變數和方法進行權限的管理,不讓自己類別外的成員任意調用或是改變值。

1. public

public 顧名思義就是公開,可以公開被讀取和寫入。
以剛剛的例子來說,可以在 name 之前加上修飾符 private,那麼創造出來的物件就無法任意改動 name 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14

class Animal {
private name: string;
constructor(name: string) {
this.name = name
}
run() {
return `${this.name} is running`
}
}

snake.name = 'Eric' // 會報錯
console.log(snake.name)

2. private / protected / readonly

將 name 的權限設成 private,所以只有自身類別可以存取使用。那如果希望可以被子類別訪問呢?則可以使用 protected。 最後 readonly 則是只能取得值而無法被更改。

example

3. static

static 屬於不會被實例化的屬性,也可以稱作靜態方法,假如類的定義和實例沒有太大關係,可以寫成靜態方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

class Animal {
readonly name: string;
// 靜態方法
static categories: string[] = ['mammal', 'bird']
static isAnimal(a) {
return a instanceof Animal
}
constructor(name: string) {
this.name = name
}
run() {
return `${this.name} is running`
}
}

console.log(Animal.categories) //[ 'mammal', 'bird' ]
console.log(Animal.isAnimal(snake)) //true

作者

Emma Shih

發表於

2020-06-03

更新於

2021-06-23

許可協議

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

評論

You forgot to set the shortname for Disqus. Please set it in _config.yml.