iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
1
Modern Web

JavaScript基本功修煉系列 第 10

JavaScript基本功修練:Day10 - for、for與while的差別、do while、break、continue

不知不覺跑鐵人賽跑到第10天了,開始前先用一段for迴圈的寫法來總結一下自己的體驗:

for(let i=0; i<30; i++){
    eat();
    code();
    writeIronMan();
    sleep();
}

一點都不誇張,難道你沒有看過這個工程師的梗?

while(alive){
    eat();
    sleep();
    code();
}

還有人把它印成T-Shirt,真是熱愛程式的孩子。自己自從學習前端開發之後就像踏上了迴圈般的踩坑生活,是無限迴圈卡關的那種(?)。

那麼迴圈是什麼意思?雖然有不同寫迴圈的方法,但簡單來說,它們的作用都是重複執行某個動作

這篇文章會針對解釋以下的迴圈寫法:

  • for
  • while
  • while 與 for 的差別
  • do while
  • break、coutinue

JS新手的我常常會用到for迴圈,但較不熟悉do whilewhile這些迴圈語法,到底我在什麼場合用到它們會較好?它們之前又有什麼差異?接下來會逐一整理。

for

首先看看大家最常用的for迴圈語法:

for (初始值; 條件; 結束時的變動) {
  // 你想重複執行的動作
}

例如:

for(let i=0; i<10; i++){
    // 你想重複執行的動作
}

大家都很熟悉這個語法,所以就不多解釋了。要注意的是最後面i++的部分,新手的我表示我曾經誤會了它運用的原理。注意,這個i是指跑完該次迴圈後i的變動,看看以下經典例子:

for(var i=0; i<5; i++){
    setTimeout( () => {
        console.log(i)
    },1000)
}

這個是講到爛的例子,大家都知道這樣的話console只會顯示五次5,並不會每隔一秒顯示0,1,2,3,4。但當時我在學習這個例子時,除了學會看懂問題就是在於var,我心裏還有一個超蠢的問題:「為什麼i是5而不是4?這裏跑了5次迴圈」

沒錯,的確跑了5次迴圈。但其實這裏的i++是指結束迴圈後的變動。而我誤會的點就是:i不是在跑迴圈後才進行遞加,i是在跑這次迴圈後,跑下一個迴圈前,進行遞加,再看看i有沒有符合條件,有的話才去跑下一個迴圈。所以,在跑完第5次迴圈時,程式碼在做以下動作:

  1. 回到for(var i=0; i<5; i++)這一行程式碼
  2. i會被遞加,變成i=5
  3. 我看看i=5有沒有符合i<5這個條件
  4. i沒有符合i<5的條件,所以我就不跑迴圈了~

程式碼知道這時候i=5,它就不會跑第6次迴圈,所以才會跑5次迴圈。回到題目,我們一共跑了4次迴圈,這時候i已經是5,而setTimeout會被執行5次,並顯示5次i的值,所以會顯示5次5。

如果硬要i是4呢? 我們可以這樣寫:

for(var i=0; i<5; i++){
    var num = i
    setTimeout( () => {
        console.log(num) 
    },1000)
}

每次跑迴圈時都把i的數值拷貝到num,所以當跑完第5次迴圈時,這時候的i變成5,就不會跑迴圈,所以num不會拷貝到5這個數值,只會維持4。

這條問題原意是想考我們如何每隔一秒,逐一把0,1,2,3,4印出來,但我這裏是針對i++的部分去做解釋,所以如果你想知道如何把隔一秒把0,1,2,3,4印出來,Google的確有不少相關文章,也推薦看看Mike老師的影片講解,除了一般用let或立即函式(IIFE)的解法外,他還有講解比較少人知道,在setTimeout傳入第三個参數的做法。

while

var i = 0 //初始值

while (條件) {
    i++ //結束時變動
}

條件true的時候,就會執行while裏面的東西。例如:

var i = 0 
while (i < 3){
    i++
}
console.log(i) //3

// 第1次迴圈:i=0  --> i++ --> i 變成 1
// 第2次迴圈:i=1  --> i++ --> i 變成 2
// 第3次迴圈:i=2  --> i++ --> i 變成 3
// i=3  -> 條件不成立 -> 不再跑迴圈

那麼whilefor有什麼分別?

  • for: 明確知道要執行迴圈多少次
  • while: 不確定要執行迴圈多少次

兩者都是迴圈,如果條件是true,就會跑迴圈。

先講for的語法,我們通常寫法就是在for後面的括號裏,寫下3個東西:初始值條件結束迴圈後的變動。所以在寫for迴圈的時候,通常我們都會確定這3個東西是什麼。初始值是什麼、條件是什麼、結束迴圈後會做什麼,在for的寫法裏,這些都是一目了然。

但是,有些情況下,我們並不能確定要跑多少次迴圈,舉個例子,例如我很確定知道我只需要跑5次迴圈就行,平時會寫for(var i=0; i<5; i++),快快脆脆地執行:

for(var i=0; i<5; i++){
    console.log(i)
}

但如果突然有一天,我想起i這個初始值會不斷被更改,它不一定是0的話,它可能是3,也可能是1。如果是3,迴圈只會執行1次,如果是1,迴圈就會執行4次,這就是上文提及「不確定要執行迴圈多少次」的情況。

所以,這時候while就可以大派用場了:

var i;
i = 3;

while(i < 5){
    console.log(i);
    i++
}

只要i<5這個條件是true,就會跑迴圈。對比之前for的寫法,因為我們通常做法是在for()的第一個位置就宣告變數和賦值,所以很多時那個變數只能綁死在裏面,綁死是沒有問題的,因為我們確定那個變數是不會被更改。

當然你也可以反駁,把for的括號裏的東西拆出來寫就可以了:

var i 
i = 3;

for(; i < 5 ;){
    console.log(i)
    i++
}

沒錯,for也會做到,我們需要看的是那種寫法是更合適,對比兩者,while更能表達我們這裏要處理的情況。

舉個具體例子,用1-10去表達自己肚子餓的程度,console會顯示自己吃了多少碗飯:

/***** 最餓:1 ------- 最飽:10 *****/

var hungry
var num = 1;

hungry = 6;

while( hungry < 8){
    console.log(`我吃了${num}碗飯`)
    num++
    hungry++
}

因為餓的程度是會變的,如果我超餓,就會想吃很多碗飯,但較飽時就不會,我並不能確定說我只會吃多少碗飯,所以不能確定跑多少次迴圈,這時候用while的寫法就會更適合。

如果hungry = 6:

如果hungry = 2:

do while

除了while,也有一個語法do while,跟while不同的是,do裏面的程式碼至少會跑一次。

do
   //執行動作
while (條件);

看例子就一目了然:

var x = 5

do {
    x += 1;
    console.log(x) //6
} while (x < 5)

這裏的x += 1就只會執行一次。

break 和 continue

breakcontinue的用法也是非常易明:

  • break: 跳離迴圈
  • continue:跳過一次,然後繼續下一次迴圈

continue例子:

for(var i=0; i<5; i++){
    if(i===2){
        continue;
    }
    console.log(`數字是${i}`)
}

//數字是0
//數字是1
//數字是3
//數字是4

break的例子,如果陣列有雙數,把第一個雙數印出來,並退出迴圈:

var list = [2,14,10,5,30]
for(var i=0; i<list.length; i++){
    if( list[i] % 2 !== 0){
        console.log(list[i]); //5
        break;
    }
}

總結

for:

  • 留意for括號最後面的元素是指跑完迴圈後,跑下一個迴圈前的變更

while 與 for 的差別:

  • for: 確定迴圈要跑多少次
  • while:不確定迴圈要跑多少次

do while:

  • 至少會跑迴圈一次

break、coutinue:

  • break:跳離迴圈
  • continue:跳過這次迴圈,然後繼續下一個迴圈

参考資料

重新認識 JavaScript: Day 09 流程判斷與迴圈
Difference between while loops and FOR loops?
JAVASCRIPT INFO - Loops: while and for


上一篇
JavaScript基本功修練:Day9 - 短路求值與條件運算子的應用
下一篇
JavaScript基本功修練:Day11 - 陣列基本概念
系列文
JavaScript基本功修煉31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
bs0704
iT邦新手 4 級 ‧ 2021-07-22 11:43:41

吃飯那一段的圖,測試好像是相反的,
hungry = 6 是2碗
圖是貼相反的嗎?

我要留言

立即登入留言