循环和迭代
循环提供了一种快速、简单的方法来重复执行某些操作。JavaScript 指南 的这一章介绍了 JavaScript 可用的不同迭代语句。
¥Loops offer a quick and easy way to do something repeatedly. This chapter of the JavaScript Guide introduces the different iteration statements available to JavaScript.
你可以将循环视为游戏的计算机化版本,其中你告诉某人朝一个方向迈 X 步,然后朝另一个方向迈 Y 步。例如,想法 "向东走五步" 可以用循环的方式表示:
¥You can think of a loop as a computerized version of the game where you tell someone to take X steps in one direction, then Y steps in another. For example, the idea "Go five steps to the east" could be expressed this way as a loop:
for (let step = 0; step < 5; step++) {
// Runs 5 times, with values of step 0 through 4.
console.log("Walking east one step");
}
有许多不同类型的循环,但它们本质上都做同样的事情:他们多次重复某个动作。(请注意,该数字可能为零!)
¥There are many different kinds of loops, but they all essentially do the same thing: they repeat an action some number of times. (Note that it's possible that number could be zero!)
各种循环机制提供了不同的方法来确定循环的起点和终点。在许多情况下,一种类型的循环比其他类型的循环更容易满足。
¥The various loop mechanisms offer different ways to determine the start and end points of the loop. There are various situations that are more easily served by one type of loop over the others.
JavaScript 中提供的 for 循环语句是:
¥The statements for loops provided in JavaScript are:
对于声明
¥for statement
for
循环会重复,直到指定条件的计算结果为 false。JavaScript for
循环类似于 Java 和 C for
循环。
¥A for
loop repeats until a specified condition evaluates to false. The JavaScript for
loop is similar to the Java and C for
loop.
for
语句如下所示:
¥A for
statement looks as follows:
for (initialization; condition; afterthought)
statement
当执行 for
循环时,会发生以下情况:
¥When a for
loop executes, the following occurs:
- 执行初始化表达式
initialization
(如果有)。该表达式通常会初始化一个或多个循环计数器,但语法允许使用任何复杂程度的表达式。该表达式还可以声明变量。 - 计算
condition
表达式。如果condition
的值为 true,则执行循环语句。否则,for
循环终止。(如果完全省略condition
表达式,则假定条件为 true。) statement
执行。要执行多个语句,请使用 块语句 ({ }
) 对这些语句进行分组。- 如果存在,则执行更新表达式
afterthought
。 - 控制返回到步骤 2。
示例
¥Example
在下面的示例中,该函数包含 for
语句,用于计算滚动列表中选定选项的数量(允许多项选择的 <select>
元素)。
¥In the example below, the function contains a for
statement that counts
the number of selected options in a scrolling list (a <select>
element that allows multiple selections).
HTML
<form name="selectForm">
<label for="musicTypes"
>Choose some music types, then click the button below:</label
>
<select id="musicTypes" name="musicTypes" multiple>
<option selected>R&B</option>
<option>Jazz</option>
<option>Blues</option>
<option>New Age</option>
<option>Classical</option>
<option>Opera</option>
</select>
<button id="btn" type="button">How many are selected?</button>
</form>
JavaScript
这里,for
语句声明了变量 i
并将其初始化为 0
。它检查 i
是否小于 <select>
元素中的选项数量,执行后续的 if
语句,并在每次循环后将 i
加 1。
¥Here, the for
statement declares the variable i
and initializes it to 0
. It checks that i
is less than the number of options in the <select>
element, performs the succeeding if
statement, and increments i
by 1 after each pass through the loop.
function countSelected(selectObject) {
let numberSelected = 0;
for (let i = 0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}
return numberSelected;
}
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
const musicTypes = document.selectForm.musicTypes;
console.log(`You have selected ${countSelected(musicTypes)} option(s).`);
});
do...while 语句
¥do...while statement
do...while
语句将重复执行,直到指定条件的计算结果为 false。
¥The do...while
statement repeats until a
specified condition evaluates to false.
do...while
语句如下所示:
¥A do...while
statement looks as follows:
do
statement
while (condition);
在检查条件之前,statement
始终执行一次。(要执行多个语句,请使用块语句 ({ }
) 对这些语句进行分组。)
¥statement
is always executed once before the condition is
checked. (To execute multiple statements, use a block statement ({ }
)
to group those statements.)
如果 condition
是 true
,则该语句再次执行。每次执行结束时,都会检查条件。当条件为 false
时,执行停止,控制权传递到 do...while
之后的语句。
¥If condition
is true
, the statement executes again. At the
end of every execution, the condition is checked. When the condition is
false
, execution stops, and control passes to the statement following
do...while
.
示例
while 语句
¥while statement
只要指定条件的计算结果为 true
,while
语句就会执行其语句。while
语句如下所示:
¥A while
statement executes its statements as long as a
specified condition evaluates to true
. A while
statement looks
as follows:
while (condition)
statement
如果 condition
变为 false
,则循环内的 statement
将停止执行,并且控制权将传递到循环后面的语句。
¥If the condition
becomes false
,
statement
within the loop stops executing and control passes to the
statement following the loop.
条件测试发生在循环中的 statement
执行之前。如果条件返回 true
,则执行 statement
并再次测试 condition
。如果条件返回 false
,则执行停止,并且控制权将传递到 while
之后的语句。
¥The condition test occurs before statement
in the loop is
executed. If the condition returns true
, statement
is executed
and the condition
is tested again. If the condition returns
false
, execution stops, and control is passed to the statement following
while
.
要执行多个语句,请使用块语句 ({ }
) 将这些语句分组。
¥To execute multiple statements, use a block statement ({ }
) to group
those statements.
实现例 1
¥Example 1
只要 n
小于 3
,以下 while
循环就会迭代:
¥The following while
loop iterates as long as n
is
less than 3
:
let n = 0;
let x = 0;
while (n < 3) {
n++;
x += n;
}
每次迭代时,循环都会递增 n
并将该值添加到 x
。因此,x
和 n
取以下值:
¥With each iteration, the loop increments n
and adds that value to
x
. Therefore, x
and n
take on the following
values:
- 第一遍之后:
n
=1
且x
=1
- 第二遍之后:
n
=2
且x
=3
- 第三遍之后:
n
=3
且x
=6
完成第三遍后,条件 n < 3
不再是 true
,因此循环终止。
¥After completing the third pass, the condition n < 3
is no longer
true
, so the loop terminates.
实现例 2
¥Example 2
避免无限循环。确保循环中的条件最终变为 false
,否则循环将永远不会终止!以下 while
循环中的语句将永远执行,因为条件永远不会变为 false
:
¥Avoid infinite loops. Make sure the condition in a loop eventually becomes
false
—otherwise, the loop will never terminate! The statements in the
following while
loop execute forever because the condition never becomes
false
:
// Infinite loops are bad!
while (true) {
console.log("Hello, world!");
}
标签声明
¥labeled statement
label
提供了一条带有标识符的语句,使你可以在程序的其他位置引用它。例如,你可以使用标签来标识循环,然后使用 break
或 continue
语句来指示程序是否应该中断循环或继续执行。
¥A label
provides a statement with an identifier that
lets you refer to it elsewhere in your program. For example, you can use a label to
identify a loop, and then use the break
or continue
statements
to indicate whether a program should interrupt the loop or continue its execution.
带标签语句的语法如下所示:
¥The syntax of the labeled statement looks like the following:
label:
statement
label
的值可以是任何非保留字的 JavaScript 标识符。你通过标签识别的 statement
可以是任何声明。有关使用标记语句的示例,请参见下面的 break
和 continue
示例。
¥The value of label
may be any JavaScript identifier that is not a
reserved word. The statement
that you identify with a label may be
any statement. For examples of using labeled statements, see the examples of break
and continue
below.
中断语句
¥break statement
使用 break
语句终止循环,使用 switch
语句或与带标签的语句结合使用。
¥Use the break
statement to terminate a loop,
switch
, or in conjunction with a labeled statement.
- 当你使用不带标签的
break
时,它会立即终止最内层的while
、do-while
、for
或switch
,并将控制权转移到下面的语句。 - 当你将
break
与标签一起使用时,它会终止指定的带标签语句。
break
语句的语法如下所示:
¥The syntax of the break
statement looks like this:
break;
break label;
- 语法的第一种形式终止最内层的封闭循环或
switch
。 - 语法的第二种形式终止指定的封闭标记语句。
实现例 1
示例 2:打破标签
继续声明
¥continue statement
continue
语句可用于重新启动 while
、do-while
、for
或 label
语句。
¥The continue
statement can be used to restart a
while
, do-while
, for
, or label
statement.
- 当你使用不带标签的
continue
时,它会终止最内层封闭的while
、do-while
或for
语句的当前迭代,并继续执行下一次迭代的循环。与break
语句相反,continue
并不完全终止循环的执行。在while
循环中,它跳回到条件。在for
循环中,它跳转到increment-expression
。 - 当你将
continue
与标签一起使用时,它适用于用该标签标识的循环语句。
continue
语句的语法如下所示:
¥The syntax of the continue
statement looks like the following:
continue;
continue label;
实现例 1
¥Example 1
以下示例显示了带有 continue
语句的 while
循环,该语句在 i
的值为 3
时执行。因此,n
采用值 1
、3
、7
和 12
。
¥The following example shows a while
loop with a continue
statement that executes when the value of i
is 3
. Thus,
n
takes on the values 1
, 3
, 7
, and
12
.
let i = 0;
let n = 0;
while (i < 5) {
i++;
if (i === 3) {
continue;
}
n += i;
console.log(n);
}
// Logs:
// 1 3 7 12
如果注释掉 continue;
,循环将运行到最后,你将看到 1,3,6,10,15
。
¥If you comment out the continue;
, the loop would run till the end and you would see 1,3,6,10,15
.
实现例 2
¥Example 2
标记为 checkiandj
的语句包含标记为 checkj
的语句。如果遇到 continue
,则程序终止 checkj
的当前迭代并开始下一次迭代。每次遇到 continue
时,checkj
都会重复,直到其条件返回 false
。当返回 false
时,checkiandj
语句的剩余部分完成,并且 checkiandj
重复执行,直到其条件返回 false
。当返回 false
时,程序继续执行 checkiandj
后面的语句。
¥A statement labeled checkiandj
contains a statement labeled
checkj
. If continue
is encountered, the program
terminates the current iteration of checkj
and begins the next
iteration. Each time continue
is encountered, checkj
reiterates until its condition returns false
. When false
is
returned, the remainder of the checkiandj
statement is completed,
and checkiandj
reiterates until its condition returns
false
. When false
is returned, the program continues at the
statement following checkiandj
.
如果 continue
的标签为 checkiandj
,则程序将从 checkiandj
语句的顶部继续执行。
¥If continue
had a label of checkiandj
, the program
would continue at the top of the checkiandj
statement.
let i = 0;
let j = 10;
checkiandj: while (i < 4) {
console.log(i);
i += 1;
checkj: while (j > 4) {
console.log(j);
j -= 1;
if (j % 2 === 0) {
continue checkj;
}
console.log(j, "is odd.");
}
console.log("i =", i);
console.log("j =", j);
}
for...in 声明
¥for...in statement
for...in
语句在对象的所有可枚举属性上迭代指定变量。对于每个不同的属性,JavaScript 都会执行指定的语句。for...in
语句如下所示:
¥The for...in
statement iterates a specified
variable over all the enumerable properties of an object. For each distinct property,
JavaScript executes the specified statements. A for...in
statement looks as
follows:
for (variable in object)
statement
示例
¥Example
以下函数将一个对象和该对象的名称作为其参数。然后,它迭代对象的所有属性并返回一个列出属性名称及其值的字符串。
¥The following function takes as its argument an object and the object's name. It then iterates over all the object's properties and returns a string that lists the property names and their values.
function dumpProps(obj, objName) {
let result = "";
for (const i in obj) {
result += `${objName}.${i} = ${obj[i]}<br>`;
}
result += "<hr>";
return result;
}
对于具有属性 make
和 model
的对象 car
,result
将是:
¥For an object car
with properties make
and model
, result
would be:
car.make = Ford car.model = Mustang
数组
¥Arrays
尽管使用这种方式迭代 Array
元素可能很诱人,但 for...in
语句除了数字索引之外还将返回用户定义属性的名称。
¥Although it may be tempting to use this as a way to iterate over Array
elements, the for...in
statement will return the name of your user-defined
properties in addition to the numeric indexes.
因此,在迭代数组时最好使用带有数字索引的传统 for
循环,因为如果修改 Array 对象(例如添加自定义属性或 方法)。
¥Therefore, it is better to use a traditional for
loop
with a numeric index when iterating over arrays, because the for...in
statement iterates over user-defined properties in addition to the array elements, if
you modify the Array object (such as adding custom properties or methods).
for...of 语句
¥for...of statement
for...of
语句创建一个循环迭代 可迭代对象(包括 Array
、Map
、Set
、arguments
对象等),调用自定义迭代钩子,其中包含针对每个不同属性的值执行的语句。
¥The for...of
statement creates a loop Iterating
over iterable objects (including
Array
, Map
, Set
,
arguments
object and so on), invoking a custom
iteration hook with statements to be executed for the value of each distinct property.
for (variable of object)
statement
以下示例显示了 for...of
循环和 for...in
循环之间的区别。for...in
迭代属性名称,而 for...of
迭代属性值:
¥The following example shows the difference between a for...of
loop and a
for...in
loop. While for...in
iterates
over property names, for...of
iterates over property values:
const arr = [3, 5, 7];
arr.foo = "hello";
for (const i in arr) {
console.log(i);
}
// "0" "1" "2" "foo"
for (const i of arr) {
console.log(i);
}
// Logs: 3 5 7
for...of
和 for...in
语句也可以与 destructuring 一起使用。例如,你可以使用 Object.entries()
同时循环对象的键和值。
¥The for...of
and for...in
statements can also be used with destructuring. For example, you can simultaneously loop over the keys and values of an object using Object.entries()
.
const obj = { foo: 1, bar: 2 };
for (const [key, val] of Object.entries(obj)) {
console.log(key, val);
}
// "foo" 1
// "bar" 2