循环:while 和 for

96 阅读3分钟

while循环

当条件为真时 则执行循环体内的代码 任何表达式或变量都可以是循环条件,而不仅仅是比较。在 while 中的循环条件会被计算,计算结果会被转化为布尔值。

例如, while(i != 0) 可简写为 while(i)

 let i = 3;
 while (i) { // 当 i 变成 0 时,条件为假,循环体不会执行
  console.log(i);
  i--;
 }

while (condition) { // 代码 // 所谓的“循环体” }

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

do...while 循环

循环首先执行循环体,然后检查条件,当条件为真时,重复执行循环体

 语法:
 let i = 0;
 do { // 循环体
   console.log(i);
   i++;
 } while (i < 3)

“for 循环”

首先执行 let i = 0; 然后进行检查条件 判断i 是否小于 3;如果为false 则停止循环;如果为true; 则进入循环体,i++ 是在每次循环完毕后执行

 语法:
 for(let i = 0; i < 3; i++) { // 循环体
     console.log(i)
 }
 for (let i = 0; i < 3; i++) alert(i) 
 // 开始 
 let i = 0 
 // 如果条件为真,运行下一步 
 if (i < 3) { alert(i); i++ } 
 // 如果条件为真,运行下一步 
 if (i < 3) { alert(i); i++ } 
 // 如果条件为真,运行下一步 
 if (i < 3) { alert(i); i++ } 
 // ……结束,因为现在 i == 3

内联变量声明 这里“计数”变量 i 是在循环中声明的。这叫做“内联”变量声明。这样的变量只在循环中可见。

    for (let i = 0; i < 3; i++) { 
        alert(i); // 0, 1, 2 
    } 
    alert(i); // 错误,没有这个变量。
    let i = 0;
    for (i = 0; i < 3; i++) { 
        alert(i); // 0, 1, 2 
    } 
    alert(i); // 3, 可见, 因为是在循环之外声明的。

省略句句段

for 循环的任何语句段都可以被省略。例如,如果我们在循环开始时不需要做任何事,我们就可以省略 begin 语句段。

    let i = 0; // 我们已经声明了 i 并对它进行了赋值
    for(, i < 3; i++;) { // 不需要 'begin' 语句段
        console.log( i )
    }

我们也可以移除 step 语句段:

 let i = 0;
 for (; i < 3;) {
   console.log( i++ ) 
 }

该循环与 while(i < 3) 等价

实际上我们可以删除所有语句段,从而创建出一个无限循环

  for (;;) {
    // 无限循环
  }

请注意 for 的两个 ; 必须存在,否则会出现语错误

跳出循环

   通常条件为假时,循环会终止。
   但我们随时都可以使用 `break` 指令强制退出。
   
例如,下面这个循环要求用户输入一系列数字,在输入的内容不是数字时“终止”循环。
    let sum = 0; 
    while (true) { 
      let value = +prompt("输入一个数字", ''); 
      if (!value) break; // (*) 
      sum += value; 
    } 
    alert( 'Sum: ' + sum );
如果用户输入空行或取消输入,在 `(*)` 行的 `break` 指令会被激活。它立刻终止循环,将控制权传递给循环后的第一行,即,`alert`。

根据需要,"无限循环 + `break`" 的组合非常适用于不必在循环开始/结束时检查条件,但需要在中间甚至是主体的多个位置进行条件检查的情况。

继续下一次迭代

`continue` 指令是 `break` 的“轻量版”。它不会停掉整个循环。而是停止当前这一次迭代,并强制启动新一轮循环(如果条件允许的话)

如果我们完成了当前的迭代,并且希望继续执行下一次迭代,我们就可以使用它。

下面这个循坏使用 continue 来只输出奇数

    for (let i = 0; i < 10; i++) { 
    
        //如果为真,跳过循环体的剩余部分。
        if (i % 2 == 0) continue;*
    
        alert(i); // 1,然后 3,5,7,9 
    }

对于偶数的 i 值,continue 指令会停止本次循环的继续执行,将控制权传递给下一次 for 循环的迭代(使用下一个数字)。因此 alert 仅被奇数值调用。

禁止 break/continue 在 ‘?’ 的右边

    (i > 5) ? alert(i) : continue; // continue 不允许在这个位置  

代码会停止运行,并显示有语法错误。

break/continue 标签

有时候我们需要一次从多层嵌套的循环中跳出来。

例如,下属代码中我们的循环使用了 ij, 从 (0,0)(3,3) 提示坐标 (i, j)

    for (let i = 0; i < 3; i++) { 
    
      for (let j = 0; j < 3; j++) { 
      
        let input = prompt(`Value at coords (${i},${j})`, ''); 
        
        // 如果我想从这里退出并直接执行 alert('Done!')    
           
      } 
    } 
    alert('Done!');

我们需要提供一种方法,以在用户取消输入时来停止这个过程。

在 input 之后的普通 break 只会打破内部循环。这还不够 —— 标签可以实现这一功能!

标签 是在循环之前带有冒号的标识符:

    labelName: for (...) { 
      ... 
    }

break <labelName> 语句跳出循环至标签处

    outName: for (let i = 0; i < 3; i++) { 
    
      for (let j = 0; j < 3; j++) { 
      
        let input = prompt(`Value at coords (${i},${j})`, ''); 
        
        // 如果我想从这里退出并直接执行 alert('Done!') // (*)
            if (!value) break outName;
            
            // 用得到的值做些事.....
      }  
    } 
    alert('Done!');
    

上述代码中,break outer 向上寻找名为 outer 的标签并跳出当前循环。

因此,控制权直接从 (*) 转至 alert('Done!')

总结

我们学习了三种循环:

  • while —— 每次迭代之前都要检查条件。
  • do..while —— 每次迭代后都要检查条件。
  • for (;;) —— 每次迭代之前都要检查条件,可以使用其他设置。

通常使用 while(true) 来构造“无限”循环。这样的循环和其他循环一样,都可以通过 break 指令来终止。

如果我们不想在当前迭代中做任何事,并且想要转移至下一次迭代,那么可以使用 continue 指令。

break/continue 支持循环前的标签。标签是 break/continue 跳出嵌套循环以转到外部的唯一方法。