---
# System prepended metadata

title: 筆記｜第四堂：函式設計
tags: [學習筆記, JavaScript]

---

`#JavaScript` `#六角前端課程` `#學習筆記` `#骨力走傱`

## 什麼是函式（Function）？
* 函式的型別為物件。
* 能將一段或數百行的程式碼，封裝在一個區塊裡，讓程式碼能重複使用。
* 透過呼叫函式或傳入參數，函式接收到資料後，會進行處理並回傳結果。

## 怎麼寫函式？
### 基本寫法
> 描述行為。
```javascript=
function morningAction() {
    console.log("起床");
    console.log("刷牙");
    console.log("洗臉");
    console.log("換衣服");
};

morningAction();
// 起床
// 刷牙
// 洗臉
// 換衣服
```
* 使用 `function` 宣告函式，函式名稱可自定義，有名稱的函式稱為具名函式（另有匿名函式）。
* `()` 內可放參數。
* 函式被呼叫後，會執行 `{}` 內的程式碼。`{}` 稱為作用域。
* `morningAction();` 呼叫函式。**函式需要被呼叫才會執行。**

### 函式內可再放入函式
```javascript=
function morningAction() {
    console.log("起床");
    console.log("刷牙");
    console.log("洗臉");
    console.log("換衣服");
};

function nightAction() {
    console.log("回家");
    console.log("洗澡");
    console.log("吃飯");
    console.log("刷牙");
};

function dayAction() {
    morningAction();
    nightAction();
};

dayAction();
// 起床
// 刷牙
// 洗臉
// 換衣服
// 回家
// 洗澡
// 吃飯
// 刷牙
```

## 什麼是參數？
```javascript=
function add(num1, num2) {
    console.log(num1 + num2);
};

add(1, 2); // -> 1 + 2 = 3
add(10, 20); // -> 10 + 20 = 30
```
```javascript=
function 函式名稱(參數1, 參數2) {
    console.log(參數1 + 參數2);
};

函式名稱(參數1, 參數2);
```
* `函式名稱(參數1, 參數2)` 表示此函式需要傳入參數。
* 可以透過函式名稱大概了解這個函式的目的，以上述範例來說，`add` 可能表示接下來傳入的參數，是要進行相加用的，因此謹慎命名也是很重要的。
* `{ console.log(參數1 + 參數2); }` 函式內出現參數的地方，表示參數會被傳到這些位置。
* `函式名稱(參數1, 參數2);` 傳入參數的方法，在 `()` 輸入參數，並且用 `,` 隔開第二筆參數。
* 參數只存在於 `()` 內，若對參數使用 `console.log`，會回傳 `is not defined`。

### 若設置參數，但未放入參數
```javascript=
function text(item) {
    console.log(item);
};

text(); // undefined
```
```javascript=
function add(num1,num2) {
    console.log(num1 + num2);
};

add(); // NaN
```

### 若設置參數，但只使用其中幾個參數
```javascript=
function text(item1, item2, item3) {
    console.log(item3);
};

text("a", "b", "c"); // c
```
* 只會回傳有使用到的參數，但通常會省略用不到的參數。

## 什麼是 return？
### 介紹
* `return` 可以傳出函式內，程式碼執行後的結果。
* 執行 `return` 時，會中斷函式內 `return` 之後的程式碼，這是 `return` 的副作用。
* 小結：**只要有區塊主體 `{}`，沒有 `return` 就不會回傳資料**。

### 未使用 return
```javascript=
function calcTotalScore(chineseScore, mathScore) {
    console.log(chineseScore + mathScore);
};

let totalScore = calcTotalScore(60, 60);

console.log(totalScore); // undefined
```
* 可以將函式賦值在變數上，但函式內未使用 `return` 時，是無法傳出值的，因此 `console.log` 的結果是 `undefined`。

### 使用 return
```javascript=
function calcTotalScore(chineseScore, mathScore) {
    return chineseScore + mathScore;
};

let totalScore = calcTotalScore(60, 60); // -> chineseScore + mathScore

console.log(totalScore); // 120
```
* 使用 `return` 傳出函式內的值，此時變數 `totalScore` 有成功賦值。

### 另一種 return 的寫法
```javascript=
function calcTotalScore(chineseScore, mathScore) {
    let totalScore = chineseScore + mathScore;
    return totalScore;
};

let totalScore = calcTotalScore(60, 60); // -> chineseScore + mathScore

console.log(totalScore); // 120
```
* 在函式內使用 `let` 宣告變數，並將運算結果賦值在變數上。
* 使用 `return` 傳出變數的值。

### 函式內可以有多個 return
```javascript=
function checkScore(score) {
    if (score >= 60) {
        return "及格";
    } else {
        return "不及格";
    }
    console.log("會不會回傳這段話") // 不會回傳，因為 return 會中斷作用域內的程式碼
};

let tomScore = checkScore(60);
console.log(tomScore); // 及格
```

### 淺談全域變數與區域變數的邏輯
```javascript=
let counts = 0; // 紀錄次數

function addCount() {
    counts++;
};

addCounts();
addCounts();

console.log(`您目前記錄了 ${counts} 次。`); // 您目前記錄了 2 次。
```
* 由於沒有在函式內宣告名為 `counts` 的變數，因此程式碼會往外層找，是否有名為 `counts` 的變數？若有，會將結果賦值在變數上；若沒有，則會回傳 `counts is not defined`。