# [JavaScript] 條件判斷:if..else 與 switch
###### tags: `前端筆記`
## 結論
1. 兩者都是要滿足條件才會執行內部的陳述式(statement)
2. 一般來說論效能:if > switch
3. 如果判斷的條件很明確(如特定的值)用 `switch` 比較好,範圍型判斷的話則用 `if...else` (但我還是都用 `if...else` 啦 XD)
## if...else
1. 架構可分為:條件式(condition)及陳述式(statement)
2. 需符合條件式內的條件才會執行對應的陳述式
3. 當條件符合就會停止判斷

## switch
1. 架構可分為:expression, case, [default], statement
2. 運作方式:會把 expression 傳到 case 的條件,並進行**嚴格相等(===)** => case 得到的條件為 `true` 的話才會執行對應的 statement

4. 與 `if...else` 不同,如果條件符合切記需要 `break` 才會終止,要不然就會直接認為之後的 case 都是 `true`,意即之後的 statement 都會執行
5. [default] 為選擇性,意思就和 `if...else` 中的 `else` 差不多,要加的話通常放最後面。
### 沒加 `break`
滿足第一個 `case` 但沒有 `break` = 之後所有的 `case` 直接判 `true` => statement 全執行
```javascript=
switch ('Oranges') {
case 'Oranges':
console.log('Oranges are $0.59 a pound.');
case 'Apples':
console.log('Apples are $0.32 a pound.');
case 'Bananas':
console.log('Bananas are $0.48 a pound.');
case 'Cherries':
console.log('Cherries are $3.00 a pound.');
case 'Mangoes':
case 'Papayas':
console.log('Mangoes and papayas are $2.79 a pound.');
}
// Oranges are $0.59 a pound.
// Apples are $0.32 a pound.
// Bananas are $0.48 a pound.
// Cherries are $3.00 a pound.
// Mangoes and papayas are $2.79 a pound.
```
### 可以同時多個判斷
```javascript=
var Animal = 'Giraffe';
switch (Animal) {
case 'Cow':
case 'Giraffe':
case 'Dog':
case 'Pig':
console.log('This animal will go on Noah\'s Ark.');
break;
case 'Dinosaur':
default:
console.log('This animal will not.');
}
```
### 也可以在 `case` 中新增區塊變數(Block-scope variables)
不過要記得在 `case` 後面用括號({})包起來,要不然會報錯。
```javascript=
const action = 'say_hello';
switch (action) {
case 'say_hello': { // added brackets
let message = 'hello';
console.log(message);
break;
} // added brackets
case 'say_hi': { // added brackets
let message = 'hi';
console.log(message);
break;
} // added brackets
default: { // added brackets
console.log('Empty action received.');
break;
} // added brackets
}
```
## 論效能的話哪個比較好?
~~說真的以我目前的能力我覺得我寫的出來 >>>> 效能哪個好 XD~~
網路上有大神測出來的是 `if` 效能比 `switch` 好([Switch statement for greater-than/less-than](https://stackoverflow.com/questions/6665997/switch-statement-for-greater-than-less-than)),不過我鮮少使用 `switch` 所以也什麼感覺。
## `if...else` 及 `switch` 的使用時機?
如果有明確的判斷值,用 `switch` 比較合適,但如果是「範圍」的話則使用 `if...else`。另外值得注意的是使用 `switch` 判斷條件都是嚴格比較(===)所以下方的例子最後會執行 `default`,因為在 JavaScript 的眼中的比較是是 `12(age) === (12 > 18)`,嚴格比較不會自動轉型,所以最後會跑 `default`。
```javascript=
function checkAge(age){
switch(age){
case (age > 18):
console.log('case 1')
break
case (age == 18):
console.log('case 2')
break
case (age < 18):
console.log('case 3')
break
default:
console.log("didn't match any one")
break
}
}
checkAge(12) // didn't match any one
```
如果想要輸出 `case 3`,就要使得比較變成 `true === (12 < 18)` 所以改一個小地方即可!
```javascript=
function checkAge(age){
switch(true){ // HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
case (age > 18):
console.log('case 1')
break
case (age == 18):
console.log('case 2')
break
case (age < 18):
console.log('case 3')
break
default:
console.log("didn't match any one")
break
}
}
checkAge(12)
```
## 考題
昨天組員丟出一個問題,為什麼用 `for` 的話就只會出現一次的 `console.log` 而不是像第一個範例一樣全部印出來呢?
```javascript=
let num = 2;
switch(num){
case 1:
console.log(`1`);
case 2:
console.log(`2`);
case 3:
console.log(`3`);
case 4:
console.log(`4`);
case 5:
console.log(`5`);
}
// 輸出:2,3,4,5
let num = 2;
for(let i = 1 ; i <= 5 ; i++){
switch(num){
case i :
console.log(num);
}
}
// 輸出:2
```
:::spoiler 答案([ref.](https://stackoverflow.com/questions/51846300/how-to-use-switch-statement-inside-for-loop))
因為每次 `for loop` 都在「重新宣告」switch,並不像第一個例子一樣是直接寫在一起的,所以當滿足 case 的條件,也只會顯示一次的 statement。
```javascript=
// first loop:
switch(num) {
case 1: {
console.log('hi');
}
}
// second loop:
switch(num) {
case 2: {
console.log('hi');
}
}
....
```
:::
## 參考資料
1. [if...else](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/if...else)
2. [switch](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/switch)
3. [[JS] Switch Case 的使用](https://pjchender.dev/javascript/js-switch-case/)
4. [[野人獻曝] Javascript 中 switch 的彈性用法](https://ithelp.ithome.com.tw/articles/10210319)
5. [Switch statement for greater-than/less-than](https://stackoverflow.com/questions/6665997/switch-statement-for-greater-than-less-than)