Skip to content

JavaScript For 循环

循环 (Loops) 是编程中一个基础的结构,它允许你重复执行一段代码块。当你需要对多个项执行相同的操作,或者需要执行代码特定次数时(通常在每次迭代中使用不同的值),循环就显得尤为有用。

循环对于自动化重复性任务至关重要。例如,在处理数组时:

// 不使用循环,处理数组项会很重复:
let output = "";
const cars = ["BMW", "Volvo", "Saab", "Ford", "Fiat", "Audi"];
output += cars[0] + "\n";
output += cars[1] + "\n";
// ...以此类推处理所有 cars
// console.log(output); // 这将打印前两辆车

循环提供了一种更高效、更具扩展性的方式来处理此类任务。

JavaScript 支持几种类型的循环:

  • for:执行一个代码块特定次数。在你已知迭代次数时非常理想。
  • for...of:遍历可迭代对象(如 Arrays、Strings、Maps、Sets 等)的值。(现代且推荐用于数组/字符串)。
  • for...in:遍历对象的可枚举属性(键)。主要用于对象,不推荐用于数组。
  • while:只要指定条件为真,就循环执行一段代码块。条件在每次迭代之前检查。
  • do...while:与 while 类似,但代码块会至少执行一次,然后才检查条件。
  • 数组方法,如 forEach()、map()、filter():提供简洁的方式来遍历和转换数组元素(通常在数组相关章节中介绍)。

传统的 for 循环是一个功能多样的工具,特别是在你需要对迭代过程进行精细控制时(例如,特定的起始/结束点,自定义的增量)。

for 循环具有以下语法:

for (initialization; condition; finalExpression) { // 当 condition 为 true 时执行的代码块 }

initialization (语句 1):在循环开始前执行一次。通常用于声明和初始化循环计数器变量(例如,let i = 0)。

condition (语句 2):在每次循环迭代前进行评估。如果为 true,则执行代码块。如果为 false,则循环终止。

finalExpression (语句 3):在每次循环迭代结束时,即代码块执行后执行。通常用于增加或减少循环计数器(例如,i++,i--)。

let textOutput = "";
for (let i = 0; i < 5; i++) {
textOutput += `The number is ${i}\n`;
}
console.log(textOutput);
/* Output:
The number is 0
The number is 1
The number is 2
The number is 3
The number is 4
*/

从上面的示例中,你可以看到:

initialization 部分 (let i = 0;) 声明了一个循环计数器 i 并将其初始值设置为 0。这只发生一次。

condition 部分 (i < 5;) 在每次迭代之前进行检查。只要 i 小于 5,循环就会继续。

finalExpression 部分 (i++;) 在每次迭代的代码块执行后,将 i 的值增加 1。

通常,initialization 语句用于使用 let 声明和初始化一个循环计数器变量。例如,let i = 0;。

initialization 语句是可选的。如果省略,你通常会在循环开始前初始化你的循环变量。

你可以在 initialization 语句中声明和初始化多个变量,用逗号分隔。当使用 let 声明时,如果它们是单独的声明,则每个变量需要自己的 let;如果是一组逗号分隔的列表,则使用一个 let。

const cars = ["Volvo", "BMW", "Mazda"];
let text = "";
// Initializing i and len. 'let' is used once for multiple declarations here.
for (let i = 0, len = cars.length; i < len; i++) {
text += cars[i] + "\n";
}
console.log(text);
/* Output:
Volvo
BMW
Mazda
*/

如果你的变量在循环开始前已经设置,你可以省略 initialization 语句:

const cars = ["Volvo", "BMW", "Mazda", "Ford"];
let i = 1; // Variable initialized before the loop
const len = cars.length;
let text = "";
for (; i < len; i++) { // Initialization statement is omitted
text += cars[i] + "\n";
}
console.log(text);
/* Output:
BMW
Mazda
Ford
*/

condition 语句在每次迭代之前进行评估。它通常涉及循环计数器,并决定循环是否应继续。

condition 语句也是可选的。

如果 condition 的评估结果为 true(或一个真值 truthy value),则执行循环的代码块。如果评估结果为 false(或一个假值 falsy value),则循环终止。

注意:如果你省略了 condition 语句,你必须在循环的代码块内的某个地方包含一个 break 语句来防止无限循环。无限循环会导致你的浏览器或程序挂起。break 语句将在稍后的章节中介绍。

finalExpression 在每次循环的代码块执行后执行。它通常用于更新循环计数器(例如,i++,i += 2)。

与其他部分一样,finalExpression 是可选的。如果需要,你可以在循环的代码块内部执行更新逻辑。

finalExpression 可以执行各种操作,例如递减 (i--),以更大的步长递增 (i += 5),甚至更复杂的表达式。

你也可以省略 final expression(例如当你需要在循环内部递增变量值时):

const cars = ["Volvo", "BMW"];
let text = "";
let i = 0;
const len = cars.length;
for (; i < len; ) { // Final expression is omitted
text += cars[i] + "\n";
i++; // Counter incremented inside the loop body
}
console.log(text);
/* Output:
Volvo
BMW
*/

对于迭代 Arrays、Strings、Maps、Sets 等可迭代对象,for...of 循环提供了更简洁、更直接的语法。它迭代的是可迭代对象的值。

for (const variable of iterable) { // 对于每个值执行的代码块 }

数组示例:

const colors = ["red", "green", "blue"];
let output = "";
for (const color of colors) {
output += color + "\n";
}
console.log(output);
/* Output:
red
green
blue
*/

字符串示例:

const message = "Hello";
for (const char of message) {
console.log(char);
}
/* Output:
H
e
l
l
o
*/

当你只需要遍历数组或其他可迭代对象的元素,而不需要索引访问或复杂的初始化/增量逻辑时,通常推荐使用 for...of 循环而不是传统的 for 循环。

JavaScript 的 for...in 语句迭代对象所有可枚举的属性名(键)。它主要设计用于迭代对象的键。

for (const key in object) { // 检查属性是否是自身属性至关重要 if (Object.hasOwnProperty.call(object, key)) { // ‘key’ 是属性名称 // ‘object[key]’ 是属性值 // 在此处处理自身属性 } }

for...in 循环内的代码块将对每个可枚举的属性键执行一次。

遍历对象的属性:

const person = {
fname: "John",
lname: "Doe",
age: 25
};
let info = "";
for (const key in person) {
// 最好检查一下这是否是对象自身的属性
if (Object.hasOwnProperty.call(person, key)) {
info += `${key}: ${person[key]}\n`;
}
}
console.log(info);
/* Output (对于旧引擎,顺序可能会有所不同):
fname: John
lname: Doe
age: 25
*/

对于仅迭代对象的自身属性,现代替代方法如 Object.keys(obj).forEach()、Object.values(obj).forEach() 或 Object.entries(obj).forEach()(或结合 for...of 使用这些方法)通常是首选,以获得更好的控制和清晰度。更多详情请参阅循环章节。

while 循环和 do...while 循环将在下一章节中解释。