JavaScript Day 16. 回圈(for、while、do while、break、continue)

今天要写的内容,是我完全没有练习过,也没有在课堂上学过的方法,那麽为什麽我还是要写这篇文章呢?原因是因为,即使在我的课程里 for 回圈算是被 forEach 取代,我却仍然可以在各个地方看到 for 回圈,这其实让我蛮慌的....

因此今天我就逼自己自学 for 回圈了,严格来说在写这篇文章前,其实已经有对 for 回圈做了一点笔记,但因为疏於练习,其实也忘的差不多了(汗),今天就当作复习吧。

回圈

重复执行一组程序码,并且检测条件,如果检测结果为 true 就会继续执行,直到检测到 false 才会停止执行;我们可以想像成仓鼠跑滚轮,如果都没有任何 false,就会无限的跑下去。

回圈有很多种形式,但在这里只会拿几个出来讨论:

  1. for
  2. while
  3. do...while
  4. break
  5. continue

for

当变数值与设定值的条件符合就会执行,直到不符合为止。

语法:

for ( 变数 = 初始值 ; 变数 < 条件值 ; 变数 + 步进值 ) {
 // 要执行的程序码
}

执行 for 回圈时,会有以下过程:

  • 如果条件符合,变数 = 初始值便会被执行。变数的部分可以自定义。
  • 变数 < 条件值 这里的条件会先被检测,如果符合 true 便会执行,如果是 false 便会终止回圈,这边如果没有设定条件,则会形成无限回圈。
  • 变数 + 步进值 会对每一次的执行产生变化。

简易实例操作:

我有一座农场,里面有 400 只猪、700只鸡、2000 只牛、10 只羊,我的农场动物加总。

let farmAnimals = [ 400, 700, 2000, 10 ];
let animal_num = 0;

for ( let i=0; i<farmAnimals.length; i++) {
    animal_num += farmAnimals[i];
}

console.log( animal_num ); // 3110

如果情境改成这样:

我有一座农场,里面有 400 只猪、700只鸡、2000 只牛、10 只羊,除了猪以外我有多少动物。

let farmAnimals = [ 400, 700, 2000, 10 ];
let animal_num = 0;

for ( let i=1; i<farmAnimals.length; i++) {
    animal_num += farmAnimals[i];
}

console.log( animal_num ); // 2710

以上两个范例,大略的解释一下发生了什麽事,第一个范例 animal_num = 0 因此我们初始值为 0 ,i=0 於是从 farmAnimals 阵列第 0 笔资料开始跑,跑到 farmAnimals 阵列资料的最後一笔数量 10,并且设定跑到第四次就会停止,也就是上面 i<farmAnimals.length 这个条件,在步进值(每一次回圈产生变化)的地方设定 i = i + 1 最後获得了所有资料的加总。

那麽第二个范例为什麽数字变了?因为 i=1 的情况下,是从 farmAnimals 阵列第 1 笔资料开始跑,因此猪的部分就没有被计算进去了。

while

只要指定的条件为 true 就执行,直到条件不符合为止,不过与 for 回圈不同的地方是,for 适合需要跑完全部阵列的情况;while 比较适合用在以条件当作终止条件的时候,譬如:比较大小、布林值。

语法:

while (condition)
  statement

直接进行范例:

// 范例:印出 1 ~ 5
let i = 1;
// i <= 5 为终止条件
while (i <= 5){
   console.log(i);
   i++
}
//1, 2, 3, 4, 5

这里要注意的是,如果底下 i++ 忘记放,会造成严重的後果,这个回圈会不停的运转,浏览器会直接爆炸,因此在练习的时候也要注意不要忘了写上去。

这个范例为,只要 a 小於 3,便会不断的重复执行:

let a = 0;
let b = 0;
while (a < 3) {
  a++;
  a += b;
}

每一次叠代都会增加 a 的值,并且把值加到 b 上面,分析起来为以下状况:

  • 第一次回圈 a = 1、b = 1
  • 第二次回圈 a = 2、b = 3
  • 第三次回圈 a = 3、b = 6

所以在第三次会判断 a 不小於 3 (不是 true),而终止回圈。

每进入一次循环体我们就称为一次叠代,假设进入三次就称为三次叠代

do while

while 是先检查终止条件,再执行回圈;do while 则是先执行回圈,再检查终止条件,因此 do while不管条件是否为 true,都会至少跑一次,接着 while 判断条件是否要继续执行,若要执行就会进行第二轮,不执行则跳出回圈;要注意的是,while 的小括号是回圈结束的地方,後面要加上分号,并且要确认无误後再开始测试回圈。

语法:

do
  陈述式
while (条件式);

这个范例中,do 回圈重复至少一次,并且他会继续不断重复到 a 不再小於 5。

let **a = 0;
do {
  a += 1;
  console.log(a);
} while (a < 5);**

break

break 意思为中断整个回圈,当我们希望他满足条件就停下来而不用全部跑完的时候,就可以使用 break。

范例:

let farmAnimals = [
    {
        animal: 'pig',
        num: 400,
    },
    {
        animal: 'chick',
        num: 700,
    },
    {
        animal: 'cow',
        num: 2000,
    },
		{
        animal: 'sheep',
        num: 1000,
    }
]

我们先建立一个阵列资料,然後示范一个正常能够捞出资料的回圈,可以看见他会跑完所有的资料:

for(var i=0; i<farmAnimals.length; i++){
    console.log(farmAnimals[i].num); // 400, 700, 2000, 10
}

假如我们希望这个回圈只帮我们捞出猪,这时候就可以使用 break 方法。

for(let i=0; i<farmAnimals.length; i++){
    if(farmAnimals[i].num < 1000){
        console.log(farmAnimals[i].animal);
        break;
    }
}

另外,这里不会跳出数量也小於 1000 的鸡,是因为回圈在跑了一次之後,已经达成了条件并且被中断,因此不会再跑第二次,此时就不会检测到第二笔鸡的资料了。

continue

continue 会满足条件後直接继续下一次的回圈。

我们知道除了 break 方法以外,其他回圈方法都会跑满每一个步骤,在这里 continue 则是只跑满足的条件。

举例来说,我有一座农场,农场里有好几座场房,每一个场房都要隔出三个区块,这三个区块里面至少要有一个区块是养鸡,以其他回圈来说,100个场房里面的三个区块都会跑过一遍,而 continue 则是在一个场房的区块里面只要检查到有一区是养鸡的,则会跳过另外两区,直接检查下一间场房,范例如下:

for(let i = 0; i <= 100; i++){
    console.log(`正在找第 ${i} 间场房`);
    if(左边){
        console.log("找到了,下一间")
        continue;
    }
    if(中间){
        console.log("找到了,下一间")
        continue;
    }
    if(右边){
        console.log("找到了,下一间")
        continue;
    }
    console.log("没有鸡")
}

使用 continue 如果在一间场房里面发现一个区块有养鸡,就会直接进行下一间,不会再跟你说「还有两区没有养鸡哦」,但是跑完 100 间场房後发现都没有养鸡的时候,就会跟你说「你这个农场都没有鸡」。

为了介绍回圈方法,自己也在撰写的过程中努力的尝试理解,很开心替自己的小脑袋增加了新的知识。另外,在使用回圈的时候,为了避免无限回圈,确定回圈内的判断式终究会变成 false 这件事真的很重要,否则造成程序大当机可是会很麻烦的,我在测试的过程中有好几次浏览器动弹不得,这篇文让我不停的冷汗直流.......

参考资料:
MDN
30 天 Javascript 从入门到进阶:回圈
回圈笔记


<<:  Day10-Kubernetes 那些事 - Ingress 篇(二)

>>:  Day17 Grafana (gRPC, Go Processes, Redis)

#8 Web Crawler 1

今天终於要开始写点有用的东西了:网路爬虫。 这次我们就来爬铁人赛的文章吧。 设定希望的资料结构 在做...

Day 30 - Final

2021 年对我来说是个意义非凡的一年。 在去年的这个时间点,我完成了 2020 iThome 铁人...

我们的基因体时代-AI, Data和生物资讯 Day16- 视觉浏览定序档案格式SAM, BAM的工具

上一篇我们的基因体时代-AI, Data和生物资讯 Day15- 组装後的序列档案格式SAM, BA...

python30天-DAY30

铁人挑战30天就这样结束拉,这是第一次参加发文类的比赛,如果在文章内有语意不通顺或是打错字的请各位多...

Day 20:专案04 - Facebook爬虫01 | ChromeDriver、Selenium

图片来源:https://unsplash.com/photos/m_HRfLhgABo 安安,今...