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 标签
有时候我们需要一次从多层嵌套的循环中跳出来。
例如,下属代码中我们的循环使用了 i
和 j
, 从 (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
跳出嵌套循环以转到外部的唯一方法。