<style>
.slides img{background-color:grey!important}
.slides img[title^='"']{filter:invert(100%)}
hr, .slides [title^='*']{display:none}
summary h1{display:inline;border-bottom:0!important}
</style>
<!-- .slide: data-background="black" -->
###### [JavaScript 教學/](/@NCHUIT/js)
:::spoiler {state=open}<h1>流程控制</h1>
+ <i class="fa fa-book"></i> 網頁 md.nchuit.cc/js
+ <i class="fa fa-tv"></i> 簡報 md.nchuit.cc/js3
- [MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Control_flow_and_error_handling)
- [w3schools](https://www.w3schools.com/js/js_booleans.asp)
[ToC]
:::
> [name=VJ]
----
## 條件判斷
有了 [布林值邏輯運算](/h1l_j7hySAuLQIMCo36K7Q?view#邏輯運算) 和 [比較運算](/h1l_j7hySAuLQIMCo36K7Q?view#比較運算) 的基礎後我們可以讓程式幫我們判斷,以區分要執行的時機,下面每個判斷完執行的地方都可以使用 [區塊](/_gdXTROLSK-x65Keydl_Ng?view#區塊) 來替代。
---
### [if...else](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/if...else)
JavaScript 中沒有 `elseif`、`elif`
就只有 `if` 跟 `else` 而已
```javascript=
if (條件1)
執行1
else
if (條件2)
執行2
else
if (條件3)
執行3
...
else
執行N
```
----
那其實稍微將它排版...
```javascript=
if (條件1)
執行1
else if (條件2)
執行2
else if (條件3)
執行3
...
else
執行N
```
好看多了
----
:::spoiler 練習: `BMI+.html`
```htmlembedded= [5]
<script>
身高 = prompt('請輸入身高(cm)')
體重 = prompt('請輸入體重(kg)')
BMI = 體重/(身高*.01)**2
if(BMI < 18.5) 狀態 = '過輕'
else if(BMI < 25) 狀態 = '正常'
else if(BMI < 30) 狀態 = '過重'
else 狀態 = '肥胖'
alert(`身高: ${身高}
體重: ${體重}
BMI: ${BMI}(${狀態})`)
</script>
```
:::
試用輸出入寫一個 BMI 計算器 [...wiki](https://zh.wikipedia.org/wiki/%E8%BA%AB%E9%AB%98%E9%AB%94%E9%87%8D%E6%8C%87%E6%95%B8)
正常範圍是 $18.5$ ~ $25$,公式:
$$
BMI = 體重(kg) / 身高^2(m^2)
$$
例如一個$52kg$的人,身高是$155cm$,則
$$
52/1.55^2 = 21.6(kg/m^2)
$$
👉這次要告訴我你算出來的是👈
👉`過輕`、`正常`、`過重`還是`肥胖`👈
----
::: spoiler 練習: [閏年](https://zh.wikipedia.org/wiki/闰年)判斷
解
```javascript=
y = prompt('輸入年份讓程式判斷是否為閏年')
if(y%4!=0) alert('平年')
else if(y%4==0 && y%100!=0) alert('閏年')
else if(y%100==0 && y%400!=0) alert('平年')
else if(y%400==0) alert('閏年')
else alert('平年')
```
縮短
```javascript=
y = prompt('輸入年份讓程式判斷是否為閏年')
if(y%4==0 && y%100!=0 || y%400==0) alert('閏年')
else alert('平年')
```
:::
輸入年份讓程式判斷是否為閏年
閏年定義
: 非4的倍數,為平年。
4的倍數但非100的倍數,為閏年。
100的倍數但非400的倍數,為平年。
400的倍數為閏年。
範例
```
輸入: 1600
輸出: 閏年
```
```
輸入: 1000
輸出: 平年
```
----
### 條件運算子(三元運算子)
```javascript=
voteable = (age < 18) ? "Too young":"Old enough"
```

----
### [switch](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/switch)
和同型態的東西做等於比較(`==`),會執行 `case` 後`:`以下到 `break` 的程式
case
: 狀況,搭配比對的值寫成`case x:`
default
: 其他情況,相當於`else if` 完最後的 `else`
break
: 跳脫當前區塊,迴圈也會用到
----
範例
```javascript=
輸入的水果=prompt('輸入水果以查看價格')
switch (輸入的水果) {
case "橘子": alert("橘子 NT$6/顆"); break
case "蘋果": alert("蘋果 NT$5/顆"); break
case "香蕉": alert("香蕉 NT$40/斤"); break
case "櫻桃": alert("櫻桃 NT$25/斤"); break
case "芒果": alert("芒果 NT$50/個 買一送一"); break
case "木瓜": alert("木瓜 NT$30/個 買二送一"); break
default: alert(`我們沒有 ${輸入的水果}`);
}
```
----
不`break`?
```javascript=
結果=''
switch(prompt('輸入東西')){
case 'test': 結果+='hello '
default: 結果+='world'
}
alert(結果)
```
---
## 迴圈
[](https://store.line.me/stickershop/product/1428520)
### 循環 while
不停判斷,成立就執行,除非`break`或
語法
```javascript=
while (判斷式)
無腦執行
```
----
範例(前面)
```javascript=
you={}
love=function(...引數){
alert('❤️❤️❤️❤️❤️')
}
while(true)
{love(you);} // 關掉分頁才能停呦
```
----
### 陣列 Array(回顧)
```javascript
陣列 = [123, 'word', true, 3.14]
```
取用陣列某一個東西:`陣列[0]`、`陣列[1]`
| 索引 | 陣列的東西 |
| ---- | -------- |
| 0 | `123` |
| 1 | `'word'` |
| 2 | `true` |
| 3 | `3.14` |
值得一提的是:它能將 *不同型態* 的資料放在一起
----
`while` 其他用處
```javascript=
陣列 = [123, 'word', true, 3.14]
索引 = 0
while(索引 < 4){
alert(`第${索引}個: ${陣列[索引]}`)
索引 = 索引 + 1//或 索引+=1 或 索引++ 或 ++索引
}
```
[👉宣告](https://www.w3schools.com/js/js_assignment.asp)
----
### 先做再循環 do...while
語法
```javascript=
do
先執行
while (判斷)
```
範例
```javascript=
do
密語=prompt('請輸入通關密語')
while(密語!='芝麻開門')
```
----
### 跳脫迴圈 break
通常搭配 `if` 使用
```javascript= [3,4,6]
do{
密語=prompt('請輸入通關密語')
if(密語=='我阿拉丁') break
alert('檢查密語...')
}while(密語!='芝麻開門')
alert('通關!')
```
### 下一輪 continue
通常搭配 `if` 使用
```javascript= [3,4,6]
do{
密語=prompt('請輸入通關密語')
if(密語=='我阿拉丁') continue
alert('檢查密語...')
}while(密語!='芝麻開門')
alert('通關!')
```
---
### 疊代 for
[「疊代」還「迭代」?](https://ryo6.medium.com/請問到底是在-疊代-或是在-迭代-f5bdba4c31eb)
語法
```javascript=
for ([初始化]; [判斷式]; [變化式])
無腦執行
```
----
Before
```javascript= [|2,3,5]
陣列 = [123, 'word', true, 3.14]
索引 = 0
while(索引 < 4){
alert(`第${索引}個: ${陣列[索引]}`)
索引++
}
```
After
```javascript= [|2]
陣列 = [123, 'word', true, 3.14]
for(索引 = 0; 索引 < 4; 索引++){
alert(`第${索引}個: ${陣列[索引]}`)
}
```
----
### 拼接字串
你可以使用 `+` 號來拼接字串。試著輸入以下幾行程式,每次一行:
```javascript=
var name = 'Bingo'
name
var hello = ' says hello!'
hello
var greeting = name + hello
greeting
```
----
### 賦值運算
如果你只是簡單想將兩個字串加在一起,你可以這樣做:
```javascript
name += ' says hello!'
```
<p>相當於</p>
```javascript
name = name + ' says hello!'
```
----
通常流程處理才用得上
|賦值運算|範例|等義於
|-|-|-
|`=`|`x = y`|`x = y`
|`+=`|`x += y`|`x = x + y`
|`++`|`x++`; `++x`|`x += 1`
|`-=`|`x -= y`|`x = x - y`
|`--`|`x--`; `--x`|`x -= 1`
----
|賦值運算|範例|等義於
|-|-|-
|`*=`|`x *= y`|`x = x * y`
|`**=`|`x **= y`|`x = x ** y`
|`/=`|`x /= y`|`x = x / y`
|`%=`|`x %= y`|`x = x % y`
----
2進制處理賦值運算
|賦值運算|範例|等義於
|-|-|-
|`<<=`|`x <<= y`|`x = x << y`
|`>>=`|`x >>= y`|`x = x >> y`
|`>>>=`|`x >>>= y`|`x = x >>> y`
|`^=`|`x ^= y`|`x = x ^ y`
|`&=`|`x &= y`|`x = x & y`
|`\|=`|`x \|= y`|`x = x \| y`
----
:::spoiler 練習: 不執行,說出下面每行`alert`出現的數字
1. 1,2
2. 3,3
3. 4,4
4. 4,3
5. 4,4
6. 5,5
7. 14
8. 64
+
9. 3
10. 4
11. 22 (0b10110)
12. 6 (0b110)
13. $2^{31}-1$
14. 11 (0b1011)
15. 0
16. 30 (0b11110)
:::
```javascript=
x=1; alert(x++); alert(x)
x=2; alert(++x); alert(x)
x=3; alert(x+=1); alert(x)
x=4; alert(x--); alert(x)
x=5; alert(--x); alert(x)
x=6; alert(x-=1); alert(x)
x=7; alert(x*=2); alert(x)
x=8; alert(x**=2); alert(x)
x=9; alert(x/=3); alert(x)
x=10; alert(x%=6); alert(x)
x=0b1011; alert(x<<=1); alert(x) //11=0b1011
x=0b1100; alert(x>>=1); alert(x) //12=0b1100
x=-1; alert(x>>>=1); alert(x) //-1=0b1...1(32個1)
x=0b1110; alert(x^=0b0101); alert(x) //14=0b1110
x=0b1111; alert(x&=0); alert(x) //15=0b1111
x=0b10000;alert(x|=0b01110);alert(x) //16=0b10000
```
----
#### [for...of](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of): 主要用於[陣列](https://www.youtube.com/watch?v=ZPMjRuVKplQ&t=46s)
```javascript=
陣列 = ['骯髒丹', 24, '尖頭拉瑞'];
for(內容物 of 陣列)
alert(內容物)
// 輸出:
// 骯髒丹
// 24
// 尖頭拉瑞
```
----
#### [for...in](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/for...in): 主要用於物件
```javascript=
某人 = {年齡:18,性別:'女',高中畢業:true}
for (屬性 in 某人)
alert(`某人.${屬性}=${某人[屬性]}`)
// 輸出:
// 某人.年齡=18
// 某人.性別=女
// 某人.高中畢業=true
```
當然你想給陣列用也是沒問題
```javascript=
陣列 = ['骯髒丹', 24, '尖頭拉瑞']
for (索引 in 陣列)
alert(`陣列[${索引}]=${陣列[索引]}`)
// 輸出:
// 陣列[0]=骯髒丹
// 陣列[1]=24
// 陣列[2]=尖頭拉瑞
```
----
:::spoiler 練習: 印星星
```javascript=
n = prompt('輸入數字n,將印出 n*n 的星星方陣')
結果 = ''
for (i = 0; i++ < n;){
for (j = 0; j++ < n;)
結果+='*'
結果+='\n'
}
alert(結果)
```
:::
輸入一個數字`n`
印出 `n*n` 的星星方陣
例
```
輸入:3
輸出:
***
***
***
```
----
## 偵錯 [try...catch](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/try...catch)
當你知道某一段程式碼可能會出錯但你又想正常執行
```javascript=
try {
沒定義的變數
} catch (錯誤) {
console.error(錯誤);
// 注意: 不同瀏覽器的錯誤訊息不一樣
}
alert('task failed successfully.')
```

----
回來我們的迴圈
:::spoiler 練習: [排序](https://zh.wikipedia.org/wiki/排序算法)數字陣列
解法1: JavaScript 內建排序
```javascript=
陣列.sort((a, b)=>(a - b));
```
解法2: **BUT 沒效率**
```javascript=
for(i in 陣列){
for(j = 0; j < 陣列.length-1-i; j++){
if ( 陣列[j] > 陣列[j+1] ){
[ 陣列[j] , 陣列[j+1] ]
= [ 陣列[j+1], 陣列[j] ];
}
}
}
```
...[更多方法](https://zh.wikipedia.org/wiki/排序算法)
:::
```javascript=
陣列=[6,2,3,0,4,1,5,8,9,7]
//TO-DO
console.log(陣列)
//輸出: [0,1,2,3,4,5,6,7,8,9]
```
注意陣列不固定(會[打亂](https://json-shuffle.online))
----
## 補充
### 練習: [排序](https://zh.wikipedia.org/wiki/排序算法)數字陣列
```javascript=
陣列=[6,2,3,0,4,1,5,8,9,7]
//TO-DO
console.log(陣列)
//輸出: [0,1,2,3,4,5,6,7,8,9]
```
注意陣列不固定(會[打亂](https://json-shuffle.online))
----
解法1: JavaScript 內建排序
```javascript=
陣列.sort((a, b)=>(a - b));
```
解法2: **BUT 沒效率**
```javascript=
for(i in 陣列){
for(j = 0; j < 陣列.length-1-i; j++){
if ( 陣列[j] > 陣列[j+1] ){
[ 陣列[j] , 陣列[j+1] ]
= [ 陣列[j+1], 陣列[j] ];
}
}
}
```
...[更多方法](https://zh.wikipedia.org/wiki/排序算法)
{"metaMigratedAt":"2023-06-16T21:38:22.998Z","metaMigratedFrom":"YAML","breaks":true,"description":"JavaScript教學-110-2主題社課-國立中興大學資訊科學研習社","title":"流程控制","contributors":"[{\"id\":\"e86b6571-4dea-4aa4-ba20-ece559b0e015\",\"add\":17266,\"del\":10593},{\"id\":\"6d6e3ba2-6820-4c6f-9117-f09bccc7f7aa\",\"add\":5753,\"del\":3398}]"}