原文: JavaScript Loops Explained: For Loop, While Loop, Do...while Loop, and More
在 JavaScript 中,循环被用来根据一个条件执行重复的任务。条件通常返回 true
或 false
。在定义的条件返回 false
之前,循环将持续运行。
for
循环
语法
for (initialization; condition; finalExpression) {
// 代码
}
for
循环由三个可选的表达式和代码块组成:
initializatio
- 这个表达式在执行第一个循环之前运行,通常用来创建一个计数器。condition
- 这个表达式每次在循环运行前都会被检查。如果它的值为true
,则执行循环中的statement
或代码。如果它的值为false
,则循环停止。如果这个表达式被省略,它会自动评估为true
。finalExpression
- 这个表达式在循环的每次迭代后执行。这通常是用来增加一个计数器,也可以用来减少一个计数器。
这三个表达式中的任何一个或代码块中的代码都可以被省略。
for
循环通常用于运行设定次数的代码。另外,在条件表达式 condition
被评估为 false
之前,你可以使用 break
来提前退出循环。
示例
- 遍历 0-8 的整数:
for (let i = 0; i < 9; i++) {
console.log(i);
}
// Output:
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
2. 在 condition
是 false
之前使用 break
来退出 for
循环:
for (let i = 1; i < 10; i += 2) {
if (i === 7) {
break;
}
console.log('Total elephants: ' + i);
}
// Output:
// Total elephants: 1
// Total elephants: 3
// Total elephants: 5
常见的陷阱:超出数组的边界
当对一个数组进行迭代时,很容易意外地超出数组的边界。
例如,你的循环可能试图引用一个只有 3 个元素的数组的第 4 个元素:
const arr = [ 1, 2, 3 ];
for (let i = 0; i <= arr.length; i++) {
console.log(arr[i]);
}
// Output:
// 1
// 2
// 3
// undefined
有两种方法可以修复这段代码:将 condition
设置为 i < arr.length
或 i <= arr.length - 1
。
for...in
循环
语法
for (property in object) {
// 代码
}
for...in
循环遍历一个对象的属性。对于每个属性,代码块中的代码被执行。
示例
1. 遍历一个对象的属性并将其名称和值记录到控制台:
const capitals = {
a: "Athens",
b: "Belgrade",
c: "Cairo"
};
for (let key in capitals) {
console.log(key + ": " + capitals[key]);
}
// Output:
// a: Athens
// b: Belgrade
// c: Cairo
常见的陷阱:在数组上进行迭代时出现的意外行为
尽管你可以使用 for...in
循环来迭代一个数组,但建议使用普通的 for
或 for...of
循环来代替。
for...in
循环可以遍历数组和类似数组的对象,但它不一定能按顺序访问数组索引。
另外,for...in
循环会返回数组或类数组对象的所有属性和继承属性,这可能导致意外的行为。
例如,这个简单的循环按预期运行:
const array = [1, 2, 3];
for (const i in array) {
console.log(i);
}
// 0
// 1
// 2
但是如果你使用的 JS 库直接修改了 Array
原型,for...in
循环也会对其进行迭代:
const array = [1, 2, 3];
Array.prototype.someMethod = true;
for (const i in array) {
console.log(i);
}
// 0
// 1
// 2
// someMethod
尽管直接修改像 Array
或 Object
这样的只读原型不符合最佳实践,但对于某些库或代码库来说,这可能是一个问题。
另外,由于 for...in
是针对对象的,它对数组的处理要比其他循环慢得多。
简而言之,记住只用 for...in
循环来迭代对象,而不是数组。
for...of
循环
语法
for (variable of object) {
// 代码
}
for...of
循环对许多类型的可迭代对象的值进行迭代,包括数组,以及特殊的集合类型,如 Set
和 Map
。对于迭代对象中的每个值,代码块中的代码被执行。
示例
1. 迭代一个数组:
const arr = [ "Fred", "Tom", "Bob" ];
for (let i of arr) {
console.log(i);
}
// Output:
// Fred
// Tom
// Bob
2. 迭代一个 Map
:
const m = new Map();
m.set(1, "black");
m.set(2, "red");
for (let n of m) {
console.log(n);
}
// Output:
// [1, black]
// [2, red]
3. 迭代一个 Set
:
const s = new Set();
s.add(1);
s.add("red");
for (let n of s) {
console.log(n);
}
// Output:
// 1
// red
while
循环
语法
while (condition) {
// 语句
}
while
循环以评估条件 condition
开始。如果 condition
评估为 true
,代码块中的代码将被执行。如果条件评估为 false
,代码块中的代码不被执行,循环结束。
示例
- 当一个变量小于 10 时,将其记录到控制台,并为其增加 1:
let i = 1;
while (i < 10) {
console.log(i);
i++;
}
// Output:
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
do...while
循环
语法
do {
// 语句
} while (condition);
do...while
循环与 while
循环密切相关。在 do...while
循环中,在每个迭代结束时而不是运行前检查条件 condition
。
这意味着 do...while
循环中的代码保证至少运行一次,即使 condition
已经评估为 false
。
示例
- 当一个变量小于 10 时,将其记录到控制台,并为其增加 1:
let i = 1;
do {
console.log(i);
i++;
} while (i < 10);
// Output:
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
2. 推送到一个数组,即使 condition
评估为 false
:
const myArray = [];
let i = 10;
do {
myArray.push(i);
i++;
} while (i < 10);
console.log(myArray);
// Output:
// [10]