JavaScript 循环:For 循环、While 循环及更多
在 JavaScript 中,我们使用循环来根据条件执行重复的任务。条件通常返回 true
或 false
。循环将持续运行,直到定义的条件返回 false
。
for
循环
语法
for (initialization; condition; finalExpression) {
// code
}
for
循环由三个可选的表达式组成,后面是一个代码块:
initialization
– 这个表达式在执行第一个循环之前运行,通常用来创建一个计数器。condition
– 这个表达式每次在循环运行前都会被检查。如果它的值为true
,则执行循环中的语句或代码。如果它的值为false
,则循环停止。如果这个表达式被省略,它会自动评估为true
。finalExpression
– 这个表达式在循环的每次迭代后执行。这通常用于增加一个计数器,但也可用于减少一个计数器。
这三个表达式中的任何一个或者代码块中的代码都可以被省略。
for
循环通常用于按设定次数运行代码。另外,在条件表达式评估为 false
之前,你可以使用 break
来提前退出循环。
示例
- 遍历 0-8 的整数:
for (let i = 0; i < 9; i++) {
console.log(i);
}
// Output:
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
- 在
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) {
// code
}
for...in
循环遍历对象的属性。对于每个属性,都会执行代码块中的代码。
示例
- 遍历对象的属性并将其名称和值打印到控制台:
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) {
// code
}
for...of
循环迭代许多类型的可迭代对象的值,包括数组和特殊的集合类型,如 Set
和 Map
。对于可迭代对象中的每个值,执行代码块中的代码。
示例
- 遍历一个数组:
const arr = [ "Fred", "Tom", "Bob" ];
for (let i of arr) {
console.log(i);
}
// Output:
// Fred
// Tom
// Bob
- 遍历
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]
- 遍历
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) {
// statement
}
while
循环从评估 condition
开始。如果 condition
为 true
,则代码块中的代码将被执行。如果 condition
为 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 {
// statement
} while (condition);
do...while
循环与 while
循环密切相关。在 do...while
循环中,在循环的每次迭代结束时检查 condition
,而不是在循环开始之前检查。
这意味着 do...while
循环中的代码保证至少运行一次,即使 condition
表达式的结果已经为 true
。
示例
- 当变量小于 10 时,将其打印到控制台并加 1:
let i = 1;
do {
console.log(i);
i++;
} while (i < 10);
// Output:
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
- 如果
condition
为true
,推送到一个数组:
const myArray = [];
let i = 10;
do {
myArray.push(i);
i++;
} while (i < 10);
console.log(myArray);
// Output:
// [10]