Skip to content

TypeScript - 循环

循环(Loops)是控制流结构,用于重复执行一段代码块。当需要多次执行相同的操作时,例如遍历数组元素或处理数据直到满足特定条件时,循环至关重要。

TypeScript 支持 JavaScript 中标准的循环结构。

循环大致可以分为:

  • 定次循环 (Definite Loops): 执行已知次数(例如,标准 for 循环)。
  • 不定次循环 (Indefinite Loops): 执行直到特定条件变为假(例如,while, do...while)。
  • 迭代循环 (Iteration Loops): 专门设计用于遍历集合(例如,for...of, for...in, forEach 方法)。

经典的 for 循环在你已知需要迭代多少次时是理想的选择。

for (initialization; condition; increment/decrement) {
// 要执行的代码块
}
  • initialization (初始化):** 在循环开始前执行一次(例如,let i = 0)。
  • condition (条件):** 在每次迭代前评估。如果为 true,循环继续;如果为 false,循环停止。
  • increment/decrement (递增/递减):** 在每次迭代后执行(例如,i++, i--, i += 2)。
console.log("Standard for loop:"); // 标准 for 循环:
for (let i: number = 0; i < 5; i++) {
console.log(`Iteration number: ${i}`); // 迭代次数:
}
// Output: 0, 1, 2, 3, 4 // 输出:

只要指定条件保持为 true,就执行一段代码块。条件在每次迭代之前检查。

while (condition) {
// 要执行的代码块
}
let counter: number = 0;
console.log("\nWhile loop:"); // While 循环:
while (counter < 3) {
console.log(`Counter is: ${counter}`); // 计数器为:
counter++;
}
// Output: 0, 1, 2 // 输出:

类似于 while,但条件在代码块执行之后检查。这保证了代码块至少执行一次,即使条件最初为假。

do {
// 要执行的代码块
} while (condition);
let attempts: number = 5;
console.log("\nDo...while loop:"); // Do...while 循环:
do {
console.log(`Attempt number: ${attempts}`); // 尝试次数:
attempts++;
} while (attempts < 5);
// Output: Attempt number: 5 (runs once even though condition 5 < 5 is false) // 输出:尝试次数:5(即使条件 5 < 5 为假,也运行一次)

这是现代且首选的方式,用于遍历可迭代对象(iterable objects)的值,例如数组、字符串、Map、Set 等。

for (const element of iterable) {
// 使用 element 的代码块
}
const iterableData: string[] = ["A", "B", "C"];
console.log("\nFor...of loop:"); // For...of 循环:
for (const item of iterableData) {
console.log(`Item: ${item}`); // 项目:
}
// Output: A, B, C // 输出:

遍历对象的键(属性名或作为字符串的数组索引)。

注意: 通常避免将 for...in 用于数组,因为它遍历的是作为字符串的索引,并且可能包含继承属性。对于数组,请使用 for...of 或 forEach。它更适合用于遍历对象属性。

for (const key in object) {
// 使用 key 和可选的 object[key] 的代码块
// Optional: check if property is own property: if (object.hasOwnProperty(key)) { ... } // 可选:检查属性是否为自有属性:if (object.hasOwnProperty(key)) { ... }
}
const userObject = { name: "David", age: 40, city: "New York" };
console.log("\nFor...in loop (object properties):"); // For...in 循环(对象属性):
for (const propName in userObject) {
// Use type assertion or checking if accessing value dynamically // 使用类型断言或检查是否动态访问值
console.log(`${propName}: ${userObject[propName as keyof typeof userObject]}`);
}
// Output: name: David, age: 40, city: New York (order not guaranteed) // 输出:name: David, age: 40, city: New York(顺序不保证)

这些语句改变循环内的正常执行流程:

立即终止包含它的最内层循环(for, while, do...while, switch)。执行在终止的循环后面的语句处继续。

console.log("\nBreak example:"); // Break 示例:
for (let i = 0; i < 10; i++) {
if (i === 5) {
console.log("Breaking loop at i=5"); // 在 i=5 处中断循环
break; // 退出循环
}
console.log(i);
}
// Output: 0, 1, 2, 3, 4, Breaking loop at i=5 // 输出:0, 1, 2, 3, 4, 在 i=5 处中断循环

跳过当前循环迭代的其余部分,并继续下一次迭代。循环的条件(如果适用)会重新评估。

console.log("\nContinue example:"); // Continue 示例:
for (let i = 0; i < 5; i++) {
if (i % 2 !== 0) {
continue; // 跳过奇数
}
console.log(`Even number: ${i}`); // 偶数:
}
// Output: Even number: 0, Even number: 2, Even number: 4 // 输出:偶数:0, 偶数:2, 偶数:4

一个条件永远不会变为假的循环将永远运行,可能导致程序或浏览器标签页崩溃。请确保你的循环条件最终会评估为假,或适当地使用 break。

// Example of an intentional infinite loop (e.g., in a server waiting for requests) // 有意为之的无限循环示例(例如,在等待请求的服务器中)
// while (true) {
// console.log("Running forever..."); // 永远运行...
// // Usually contains logic and potentially a break condition // 通常包含逻辑和潜在的中断条件
// }
// Example of an accidental infinite loop // 无意为之的无限循环示例
// let k = 0;
// while (k < 5) {
// console.log(k);
// // Forgot to increment k, so k < 5 is always true! // 忘记递增 k,所以 k < 5 总是为真!
// }