# 🏅 Day 3 - 函式
今天的每日任務,我們先來重溫一下 JavaScript 在宣告函式的兩種方式,分別為:
1. **函式陳述式(Function Declaration)**:傳統的函式定義方式。
2. **函式表達式(Function Expression)**:將函式賦值給變數的方式。
## 函式陳述式(Function Declaration)
函式陳述式它以 **`function`** 關鍵字當作開頭,後面接著函式名稱與對應程式碼。
**主要特性有:**
1. 函式名稱是必需的
2. 函式會被提升 **Hoisting (提升)**
**範例程式碼**:
```tsx=
console.log(add(5, 3)); // 會被提升,所以仍會輸出: 8
function add(x, y){
return x + y;
}
console.log(add(5, 3)); // 輸出: 8
```
## **函式表達式(Function Expression)**
函式表達式是將函式定義為表達式的一部分,通常是將函式賦值給變數。可以是匿名的(沒有函式名稱)或具名的。唯一的差別在,函式表達式不會被提升,所以只能在函式被賦值之後才能執行。
**主要特性有**:
1. 可以是匿名也可以是具名。
2. 不會被提升,需要在定義之後才能執行。
**範例程式碼**:
```tsx=
console.log(subtract(10, 5)); // 會出錯,Uncaught ReferenceError: subtract is not defined
const subtract = function(x, y) {
return x - y;
};
console.log(subtract(10, 5)); // 輸出: 5
```
## 函式的型別註釋
接下來我們就來了解在 TypeScript 中如何針對函式加上型別註釋吧!
你可以為函式的參數和回傳值加入型別註釋:
1. **參數型別**:定義每個參數的型別。
2. **回傳值的型別**:定義函式回傳值的型別。如果函式不回傳任何值,可以使用 **`void`**。
### 範例程式碼
**範例 1:基本函式型別**
```tsx=
function add(x: number, y: number): number {
return x + y;
}
```
**`add`** 函式有兩個參數 **`x`** 和 **`y`**,它們都是 **`number`** 型別,並且函式回傳一個 **`number`** 型別的值。
## 函式表達式與箭頭函式
在 TypeScript 中,也可以使用 ES6 的箭頭函式(Arrow Function)來簡化函式表達式。
例如,一個箭頭函式的加法函式可以寫成:
```tsx=
const add = (x: number, y: number): number => x + y;
```
另外,如果多個函式使用到重複的輸入和輸出型別,也可以透過統一定義 input 和 output 來進行型別註釋,例如:
```tsx=
type TMathNumber = {
(a: number, b: number): number
}
// 或是使用箭頭函式來定義也可以
// type TMathNumber = (a: number, b: number) => number
const add: TMathNumber = (a, b) => a + b;
const reduce: TMathNumber = (a, b) => a - b;
```
## **單選題**
1. TypeScript 中,函式陳述式的主要特點是什麼?
A. 可以被賦值給變數
B. 必須要有函式名稱
C. 都必須要回傳 **`void`**
D. 不可以有回傳值
2. 在 TypeScript 中,函式參數的型別註釋主要作用是什麼?
A. 指定函式執行的時間
B. 定義函式的參數和回傳值的型別
C. 確定函式的名稱
D. 調整函式的性能
3. 以下哪個選項正確定義了一個 TypeScript 函式,該函式接受兩個 **`number`** 類型的參數並回傳一個 **`number`**?
A. **`function add(x, y) { return x + y; }`**
B. **`const add = (x: number, y: number): number => x + y;`**
C. **`let add = function(x, y) { return x + y; }`**
D. **`add(x: number, y: number): number { return x + y; }`**
4. 如果一個 TypeScript 函式不回傳任何值,它的回傳型別應該是什麼?
A. **`number`**
B. **`string`**
C. **`void`**
D. **`boolean`**
## **實做題**
1. 設計一個 **`concatStrings`** 函式並使用函式陳述式,使函式能接收兩個 **`string`** 型別的參數,並將它們連接起來。
2. 定義一個 **`TMathNumber`** 型別,並設計 **`multiply`** 和 **`devide`** 兩個函式分別回傳兩個數字相乘和相除的結果,使用箭頭函式來設計以符合函式表達式以及 **`TMathNumber`** 型別格式。
3. 設計一個函式 **`isGreaterThanTen`** 函式陳述式,設計一個 **`number`** 型別的參數,並檢查該數字是否大於 10,回傳 **`boolean`** 值。
<!-- 解答:
單選題目:B、B、B、C
實作題:
1.
function concatStrings(str1: string, str2: string): string {
return str1 + str2;
};
2.
type TMathNumber = {
(a: number, b: number): number
}
const multiply: TMathNumber = (a, b) => a * b;
const devide: TMathNumber = (a, b) => a / b;
3.
function isGreaterThanTen(num: number): boolean {
return num > 10;
}
-->