`#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`。