沒有那麼複雜。
從 label 與 goto 來理解迴圈的本質
先介紹這兩個東西是因為不管是哪種迴圈,本質都是這三樣東西:
- 初始值
- 終止條件
- 每一圈要做的事(更新控制迴圈的變數值)
如果把每種迴圈的步驟拆出來分析,會發現背後的概念都是用label
跟 goto
來實作的。
(JavaScript 沒有這個語法,純粹只是要解釋這個概念)
1 | var i = 1 // 初始值 |
試著自己把一個步驟走過一遍:
- 建立初始值
i = 1
- loop 是標籤,不理它
- 印出
i
- 更新
i
- 終止條件,
i<=10
的話就跳回loop
- 印出
finished
最後你會發現這就跟你用迴圈的語法寫出來的結果一樣:
1 | 1 |
do while 先做再說
因為 do while 不常用,所以還蠻常忘記它的語法。一個比較直覺的想法:一個迴圈就是一個 block,所以要做(do)的事情就放在 block 裡。
do while 的流程:
- 初始值
- 每一圈要做的事(更新控制迴圈的變數值)
- 終止條件
1 | var i = 0 |
while 就是我熟悉的它
while 跟 do whie 最不一樣的地方是:「先判斷條件」,接著才執行迴圈區塊。
while 的流程:
- 初始值
- 終止條件
- 每一圈要做的事(更新控制迴圈的變數值)
單舉例子太無聊了,所以做點有趣的:
1 | var i = 0 |
i++
寫在 log 也沒問題哦!(不知道為什麼的話罰你回去看 i++ 是什麼意思)
for loop
其實 for
跟 while
的流程是一樣的:
- 初始值
- 終止條件
- 每一圈要做的事(更新控制迴圈的變數值)
只是 while
的結構寫起來沒有那麼好讀:
1 | var i = 0 // 初始值 |
for
把東西都寫在一行裡,一目了然:
1 | // 同一行所以要句點 |
在幫你複習一下,如果你用 label
跟 goto
的概念來解析 for 跟 while 的話,會發現做的事情都一樣:
1 | var i = 0 |
- 初始值
- 終止條件(不符合就跳第五步)
- 執行迴圈 block(更新控制變數的值)
- 跳回第二步
- 結束
break 與 continue
即便迴圈本身已經自帶「終止條件」,但有些時候我們會想要在執行「迴圈 block」的過程中來控制迴圈的執行流程:
- 跳出迴圈
- 忽略掉那一圈要做的事情
這個時候 break
跟 continue
就派上用場了。
break
碰到 break 時,不會執行之後的指令,直接跳出迴圈。
這裡利用 break 來在迴圈區塊中建立終止條件:
1 | var i = 0 |
儘管 while (true)
會蹦出一個「無窮迴圈」,但因為我們在迴圈區塊使用了 break 來控制流程,所以在 i=101
的時候,迴圈就會結束。
continue
碰到 continue 時,不會執行之後的指令,直接跳下一圈迴圈。
這裡寫一個碰到奇數就跳下一圈的迴圈:
1 | var i = 0 |
簡單的應用
用三種不同的迴圈來「印出分數的總和」
- do while
1 | var i = 0 |
- while
1 | var scores = [70, 32, 52, 66, 90] |
- for
1 | var scores = [70, 32, 52, 66, 90] |
i<n 跟 i<=n 的理解方式
剛開始學迴圈的時候很常會搞混 <
跟 <=
的差別。其實有個簡單的判斷法:
- i<5,只會執行到 4
- i<=5,會執行到 5
我的記法是只要看到 <=
,就表示一定會碰到 n;不是的話就是 n - 1
搭配 Array.length 使用的時候,通常都是寫 <
,因為「索引值」是從 0 開始,所以假設長度是 5,最後一個索引值就會是 4:0 => 1 => 2 => 3 => 4