03月07, 2019

JS基础(3)——流程控制(2)——循环语句

循环语句,也是流程控制语句中不可或缺的一种结构。在 JavaScript 中实现循环的方式有好几种,我们一个一个来看。

3-2-1 为什么需要循环

在具体介绍 JavaScript 中的循环之前,首先我们来明确一个问题,那就是为什么需要循环。这里举一个简单的例子,例如我们要设计一个程序,计算从 1 加到 10 的值,或许你会写出:

let i = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
console.log(i);

但是如果是从 1 加到 100 呢?或者是从 1 加到 1000 呢?显然这种方法就力不从心了。这个时候,就需要循环语句登场了。这里我们介绍 JavaScript 中的 3 种循环结构,while 循环,do..while 循环以及 for 循环。

3-2-2 while 循环

while 循环是循环里面比较常见的一种循环,它的语法如下:

while(表达式){
    // 循环体
}

含义:如果表达式成立,执行循环体,否则结束循环

while 循环示例:从 1 加到 100

let i = 1,sum = 0;
while(i <= 100){
    sum += i;
    i++;
}
console.log(sum); // 5050

无穷循环

所谓无穷循环,被被称之为死循环。这是在我们无法退出循环时会遇到的一种情况。一般来讲,我们在设计循环的时候需要为循环设计一个出口,这样才能在当不满足循环条件的时候退出循环。

如果没有正确的对循环设计一个出口,那么循环语句将无法退出,陷入到无穷循环,也就是死循环里面。所以我们在设计循环的时候,一定要注意正确的书写循环条件,以便循环能在执行一定次数以后退出。

3-2-3 do..while 循环

首先执行一次循环体,然后检测循环条件表达式的值是否为"真",如果是真的话,则重复执行循环语句。

do...while 循环和前面两种循环语句略有区别,区别在于循环至少会执行一次

它的一般形式为:

do{
    // 执行语句;
}while(表达式);

举例:用 do...while 改写上面的程序

let i = 1,sum = 0;
do{
    sum += i;
    i++;
}while(i <= 100);
console.log(sum); // 5050

3-2-4 for 循环

for 循环是所有循环里面最常见的一种循环。for 循环的一般形式为:

for(表达式1;表达式2;表达式3){
    // 循环体
}

它执行的顺序为:首先执行表达式 1,然后进行表达式 2 的判断,如果表达式 2 成立,那么执行循环体,循环体执行结束后,进行表达式 3,然后回头再看表达式 2 是否成立,成立就执行循环体,不成立该循环就结束。

for 循环举例:用 for 循环实现从 1 加到 100

let sum = 0;
for(let i=1;i<=100;i++){
    sum += i;
}
console.log(sum); // 5050

在 for 循环里面,每一个部分都是可选的,例如上面的代码,我们可以做如下的修改:

let i = 1,sum = 0;
for(;i<=100;){
    sum += i;
    i++;
}
console.log(sum); // 5050

遍历数组

最早的时候,在 JavaScript 里面就经常使用 for 循环来对数组进行遍历。示例如下:

let arr = [1,2,3,4,5];
for(let i=0;i

这里有一个小技巧,就是在使用 for 循环来遍历数组的时候,使用一个变量来存储数组的长度,这样可以大大提升程序的效率,因为不用每次都去重新计算数组的长度

let arr = [1,2,3,4,5];
for(let i=0,j=arr.length;i

3-2-5 循环的嵌套

我们可以把一个循环放在另外一个循环里面,从而构成循环的嵌套。里面的循环称之为内层循环,外面的循环称之为外层循环。外层循环每循环一次,内层循环就把自己的全部循环执行完。

循环嵌套示例:打印九九乘法表

let str = "";
for (let i = 1; i <= 9; i++) {
    for (let j = 1; j <= i; j++) {
        str += `${i}*${j}=${i*j} `;
    }
    console.log(str);
    str = "";
}
// 1*1=1
// 2*1=2 2*2=4
// 3*1=3 3*2=6 3*3=9
// 4*1=4 4*2=8 4*3=12 4*4=16
// 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
// 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
// 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
// 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
// 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

上面有提到使用 for 循环来遍历数组。一般来讲,遍历一维数组就用一个 for 循环就够了,而如果要遍历一个二维数组,就需要使用到 for 循环的嵌套,也就是双层 for 循环。而如果是三维数组,则需要使用到三层 for 循环,以此类推。

使用双层 for 循环遍历一个二维数组:

let arr = [
    ["Bill",20],
    ["Lucy",23],
    ["David",25],
    ["Lily",18]
];
for(let i=0;i

3-2-6 break 和 continue

break 语句

break 语句我们在前面讲 switch 语句的时候已经见到过了,当时有讲到它的作用是跳出 switch 语句或者循环语句。有一点需要注意的是:break 语句不能直接作用于 if 语句,除非这个 if 语句是被嵌套在循环语句里面的。

//错误
if(条件){
    //执行语句
    break;
}
//正确
for(表达式1;表达式2;表达式3){
    if(条件){
        //执行语句
        break;
    }
}

continue 语句

结束本次循环(不是终止整个循环),即跳过循环体中 continue 语句后面的语句,开始下一次循环。

break 语句和 continue 语句的区别:continue 语句的意思是结束本次循环,break 语句是结束整个循环。具体示例如下:

break 语句:

for(1;2;3){
    a;
    b;
    break; // 执行a,b后循环结束
    c;
    d;
}

continue 语句:

for(1;2;3){
    a;
    b;
    continue; // 执行a,b以后结束本次循环
    c;
    d;
}

break 和 continue 在默认情况下,是终止掉离它最近的循环。特殊情况下,我们可以通过给每个循环取一个名字,然后通过名字来终止指定循环,示例如下:

// 给数组去重复
let arr = [1, 2, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8];
let newArr = [];
outer: for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < newArr.length; j++) {
        if (arr[i] === newArr[j]) {
            continue outer; // 终止名字为outer的循环
        }
    }
    newArr.push(arr[i]);
}
console.log(newArr);

在上面的代码中,我们要给 arr 这个数组去除重复,在 ECMAScript 6 出来之前,数组去重都需要开发人员自己来书写方法。

这里我们就利用了一种最简单的去重方式,用旧数组和新数组进行比较,如果新数组里面不含有旧数组里面的元素,则将此元素放入新的数组。当我们比较的时候,发现新数组里面已经存在此元素时,就直接 continue 结束外层的循环,进入外层循环的下一次循环。

总结

  1. 所谓流程控制,主要就是用于控制整个程序的走向的。

  2. 条件语句可以分为单分支语句,双分支语句以及多分支语句。

  3. 三目运算符可以看作是双分支语句的一个 缩写形式。

  4. switch 语句是一种结构更清晰的多分支语句。涉及到的关键字有 case,break 和 default。

  5. 常见的循环结构有 while 循环,do...while 循环和 for 循环。

  6. 循环中常见的关键字有 break 和 continue,需要注意两者之间的区别。

本文链接:http://www.yanhongzhi.com/post/js-basis-7.html

-- EOF --

Comments