type
status
date
slug
summary
tags
category
icon
password
上次编辑时间
Jul 3, 2025 08:41 AM
comment
AI 总结
我们经常需要重复执行一些操作。
例如,我们需要将列表中的商品逐个输出,或者运行相同的代码将数字 1 到 10 逐个输出。
循环 是一种重复运行同一代码的方法。
for…of 和 for…in 循环
给进阶读者的一个小提示。
本文仅涵盖了基础的循环:
while
,do..while
和 for(..; ..; ..)
。如果你阅读本文是为了寻找其他类型的循环,那么:
- 用于遍历对象属性的
for..in
循环请见:for…in。
否则,请继续阅读。
“while” 循环
while
循环的语法如下:当
condition
为真时,执行循环体的 code
。例如,以下将循环输出当
i < 3
时的 i
值:循环体的单次执行叫作 一次迭代。上面示例中的循环进行了三次迭代。
如果上述示例中没有
i++
,那么循环(理论上)会永远重复执行下去。实际上,浏览器提供了阻止这种循环的方法,我们可以通过终止进程,来停掉服务器端的 JavaScript。任何表达式或变量都可以是循环条件,而不仅仅是比较。在
while
中的循环条件会被计算,计算结果会被转化为布尔值。例如,
while (i != 0)
可简写为 while (i)
:“do…while” 循环
使用
do..while
语法可以将条件检查移至循环体 下面:循环首先执行循环体,然后检查条件,当条件为真时,重复执行循环体。
例如:
这种形式的语法很少使用,除非你希望不管条件是否为真,循环体 至少执行一次。通常我们更倾向于使用另一个形式:
while(…) {…}
。“for” 循环
for
循环更加复杂,但它是最常使用的循环形式。for
循环看起来就像这样:我们通过示例来了解一下这三个部分的含义。下述循环从
i
等于 0
到 3
(但不包括 3
)运行 alert(i)
:我们逐个部分分析
for
循环:语句段 | ㅤ | ㅤ |
begin | let i = 0 | 进入循环时执行一次。 |
condition | i < 3 | 在每次循环迭代之前检查,如果为 false,停止循环。 |
body(循环体) | alert(i) | 条件为真时,重复运行。 |
step | i++ | 在每次循环体迭代后执行。 |
一般循环算法的工作原理如下:
开始运行
→ (如果 condition 成立 → 运行 body 然后运行 step)
→ (如果 condition 成立 → 运行 body 然后运行 step)
→ (如果 condition 成立 → 运行 body 然后运行 step)
→ ...
所以,
begin
执行一次,然后进行迭代:每次检查 condition
后,执行 body
和 step
。如果你这是第一次接触循环,那么回到这个例子,在一张纸上重现它逐步运行的过程,可能会对你有所帮助。
以下是在这个示例中发生的事:
内联变量声明
这里“计数”变量
i
是在循环中声明的。这叫做“内联”变量声明。这样的变量只在循环中可见。除了定义一个变量,我们也可以使用现有的变量:
省略语句段
for
循环的任何语句段都可以被省略。例如,如果我们在循环开始时不需要做任何事,我们就可以省略
begin
语句段。就像这样:
我们也可以移除
step
语句段:该循环与
while (i < 3)
等价。实际上我们可以删除所有内容,从而创建一个无限循环:
请注意
for
的两个 ;
必须存在,否则会出现语法错误。跳出循环
通常条件为假时,循环会终止。
但我们随时都可以使用
break
指令强制退出。例如,下面这个循环要求用户输入一系列数字,在输入的内容不是数字时“终止”循环。
如果用户输入空行或取消输入,在
(*)
行的 break
指令会被激活。它立刻终止循环,将控制权传递给循环后的第一行,即,alert
。根据需要,“无限循环 +
break
” 的组合非常适用于不必在循环开始/结束时检查条件,但需要在中间甚至是主体的多个位置进行条件检查的情况。继续下一次迭代
continue
指令是 break
的“轻量版”。它不会停掉整个循环。而是停止当前这一次迭代,并强制启动新一轮循环(如果条件允许的话)。如果我们完成了当前的迭代,并且希望继续执行下一次迭代,我们就可以使用它。
下面这个循环使用
continue
来只输出奇数:对于偶数的
i
值,continue
指令会停止本次循环的继续执行,将控制权传递给下一次 for
循环的迭代(使用下一个数字)。因此 alert
仅被奇数值调用。continue
指令利于减少嵌套显示奇数的循环可以像下面这样:
从技术角度看,它与上一个示例完全相同。当然,我们可以将代码包装在
if
块而不使用 continue
。但在副作用方面,它多创建了一层嵌套(大括号内的
alert
调用)。如果 if
中代码有多行,则可能会降低代码整体的可读性。禁止
break/continue
在 ‘?’ 的右边请注意非表达式的语法结构不能与三元运算符
?
一起使用。特别是 break/continue
这样的指令是不允许这样使用的。例如,我们使用如下代码:
……用问号重写:
……代码会停止运行,并显示有语法错误。
这是不(建议)使用问号
?
运算符替代 if
语句的另一个原因。break/continue 标签
有时候我们需要一次从多层嵌套的循环中跳出来。
例如,下述代码中我们的循环使用了
i
和 j
,从 (0,0)
到 (3,3)
提示坐标 (i, j)
:我们需要提供一种方法,以在用户取消输入时来停止这个过程。
在
input
之后的普通 break
只会打破内部循环。这还不够 —— 标签可以实现这一功能!标签 是在循环之前带有冒号的标识符:
break <labelName>
语句跳出循环至标签处:上述代码中,
break outer
向上寻找名为 outer
的标签并跳出当前循环。因此,控制权直接从
(*)
转至 alert('Done!')
。我们还可以将标签移至单独一行:
continue
指令也可以与标签一起使用。在这种情况下,执行跳转到标记循环的下一次迭代。标签并不允许“跳到”所有位置
标签不允许我们跳到代码的任意位置。
例如,这样做是不可能的:
break
指令必须在代码块内。从技术上讲,任何被标记的代码块都有效,例如:……尽管 99.9% 的情况下
break
都被用在循环内,就像在上面那些例子中我们看到的那样。continue
只有在循环内部才可行。总结
我们学习了三种循环:
while
—— 每次迭代之前都要检查条件。
do..while
—— 每次迭代后都要检查条件。
for (;;)
—— 每次迭代之前都要检查条件,可以使用其他设置。
通常使用
while(true)
来构造“无限”循环。这样的循环和其他循环一样,都可以通过 break
指令来终止。如果我们不想在当前迭代中做任何事,并且想要转移至下一次迭代,那么可以使用
continue
指令。break/continue
支持循环前的标签。标签是 break/continue
跳出嵌套循环以转到外部的唯一方法。