循环语句 #

一、循环语句概述 #

循环语句用于重复执行代码块。Deno支持多种循环结构:for、while、do-while、for…of和for…in。

二、for循环 #

2.1 基本语法 #

typescript
for (初始化; 条件; 更新) {
  // 循环体
}

2.2 基本示例 #

typescript
for (let i = 0; i < 5; i++) {
  console.log(i);
}
// 输出:0 1 2 3 4

2.3 倒序循环 #

typescript
for (let i = 5; i > 0; i--) {
  console.log(i);
}
// 输出:5 4 3 2 1

2.4 步长循环 #

typescript
for (let i = 0; i < 10; i += 2) {
  console.log(i);
}
// 输出:0 2 4 6 8

2.5 多变量循环 #

typescript
for (let i = 0, j = 10; i < j; i++, j--) {
  console.log(`i: ${i}, j: ${j}`);
}
// 输出:i: 0, j: 10 ... i: 4, j: 6

2.6 省略部分 #

typescript
let i = 0;
for (; i < 5; ) {
  console.log(i);
  i++;
}

三、while循环 #

3.1 基本语法 #

typescript
while (条件) {
  // 循环体
}

3.2 基本示例 #

typescript
let count = 0;

while (count < 5) {
  console.log(count);
  count++;
}
// 输出:0 1 2 3 4

3.3 读取输入 #

typescript
const inputs = ["hello", "world", "quit"];
let index = 0;

while (inputs[index] !== "quit") {
  console.log(inputs[index]);
  index++;
}
// 输出:hello world

3.4 无限循环 #

typescript
while (true) {
  const random = Math.random();
  console.log(random);
  
  if (random > 0.9) {
    break;
  }
}

四、do-while循环 #

4.1 基本语法 #

typescript
do {
  // 循环体
} while (条件);

4.2 基本示例 #

typescript
let count = 0;

do {
  console.log(count);
  count++;
} while (count < 5);
// 输出:0 1 2 3 4

4.3 至少执行一次 #

typescript
let value = 10;

do {
  console.log(value);
  value++;
} while (value < 5);
// 输出:10(至少执行一次)

4.4 用户输入验证 #

typescript
function getValidInput(): string {
  let input: string;
  
  do {
    input = "valid"; // 模拟输入
  } while (input.length < 3);
  
  return input;
}

五、for…of循环 #

5.1 基本语法 #

typescript
for (const item of iterable) {
  // 循环体
}

5.2 数组遍历 #

typescript
const fruits = ["apple", "banana", "cherry"];

for (const fruit of fruits) {
  console.log(fruit);
}
// 输出:apple banana cherry

5.3 字符串遍历 #

typescript
const str = "Hello";

for (const char of str) {
  console.log(char);
}
// 输出:H e l l o

5.4 Map遍历 #

typescript
const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3]
]);

for (const [key, value] of map) {
  console.log(`${key}: ${value}`);
}
// 输出:a: 1 b: 2 c: 3

5.5 Set遍历 #

typescript
const set = new Set([1, 2, 3, 2, 1]);

for (const value of set) {
  console.log(value);
}
// 输出:1 2 3

5.6 生成器遍历 #

typescript
function* range(start: number, end: number) {
  for (let i = start; i <= end; i++) {
    yield i;
  }
}

for (const num of range(1, 5)) {
  console.log(num);
}
// 输出:1 2 3 4 5

六、for…in循环 #

6.1 基本语法 #

typescript
for (const key in object) {
  // 循环体
}

6.2 对象遍历 #

typescript
const user = {
  name: "Alice",
  age: 25,
  city: "Beijing"
};

for (const key in user) {
  console.log(`${key}: ${user[key as keyof typeof user]}`);
}
// 输出:name: Alice age: 25 city: Beijing

6.3 数组遍历(不推荐) #

typescript
const arr = ["a", "b", "c"];

for (const index in arr) {
  console.log(`${index}: ${arr[index as number]}`);
}
// 输出:0: a 1: b 2: c

6.4 for…in vs for…of #

typescript
const arr = ["a", "b", "c"];

// for...in:遍历索引(键)
for (const key in arr) {
  console.log(key); // 0, 1, 2
}

// for...of:遍历值
for (const value of arr) {
  console.log(value); // a, b, c
}

七、数组方法替代循环 #

7.1 forEach #

typescript
const numbers = [1, 2, 3, 4, 5];

numbers.forEach((num, index) => {
  console.log(`索引 ${index}: ${num}`);
});

7.2 map #

typescript
const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

7.3 filter #

typescript
const numbers = [1, 2, 3, 4, 5];

const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]

7.4 reduce #

typescript
const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15

7.5 find和findIndex #

typescript
const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" }
];

const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: "Bob" }

const index = users.findIndex(u => u.name === "Charlie");
console.log(index); // 2

八、嵌套循环 #

8.1 二维数组 #

typescript
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

for (let i = 0; i < matrix.length; i++) {
  for (let j = 0; j < matrix[i].length; j++) {
    console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`);
  }
}

8.2 九九乘法表 #

typescript
for (let i = 1; i <= 9; i++) {
  let line = "";
  for (let j = 1; j <= i; j++) {
    line += `${j}×${i}=${i * j}\t`;
  }
  console.log(line);
}

8.3 查找元素 #

typescript
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

function findInMatrix(matrix: number[][], target: number): [number, number] | null {
  for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
      if (matrix[i][j] === target) {
        return [i, j];
      }
    }
  }
  return null;
}

console.log(findInMatrix(matrix, 5)); // [1, 1]

九、实际应用 #

9.1 分页处理 #

typescript
const items = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`);
const pageSize = 10;

for (let page = 0; page < Math.ceil(items.length / pageSize); page++) {
  const start = page * pageSize;
  const end = start + pageSize;
  const pageItems = items.slice(start, end);
  
  console.log(`Page ${page + 1}:`, pageItems);
}

9.2 批量处理 #

typescript
async function processBatch<T>(
  items: T[],
  batchSize: number,
  processor: (item: T) => Promise<void>
): Promise<void> {
  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    await Promise.all(batch.map(processor));
    console.log(`Processed ${Math.min(i + batchSize, items.length)}/${items.length}`);
  }
}

9.3 重试机制 #

typescript
async function fetchWithRetry(
  url: string,
  maxRetries: number = 3
): Promise<Response> {
  let lastError: Error | null = null;
  
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url);
      if (response.ok) {
        return response;
      }
      throw new Error(`HTTP ${response.status}`);
    } catch (error) {
      lastError = error as Error;
      console.log(`Attempt ${attempt} failed: ${lastError.message}`);
      
      if (attempt < maxRetries) {
        await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
      }
    }
  }
  
  throw lastError;
}

9.4 轮询 #

typescript
async function pollUntil(
  checkFn: () => Promise<boolean>,
  interval: number = 1000,
  timeout: number = 30000
): Promise<boolean> {
  const startTime = Date.now();
  
  while (Date.now() - startTime < timeout) {
    if (await checkFn()) {
      return true;
    }
    await new Promise(resolve => setTimeout(resolve, interval));
  }
  
  return false;
}

十、性能优化 #

10.1 减少循环内计算 #

typescript
const arr = [1, 2, 3, 4, 5];

// 不推荐:每次循环都计算length
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

// 推荐:缓存length
for (let i = 0, len = arr.length; i < len; i++) {
  console.log(arr[i]);
}

10.2 使用适当的循环 #

typescript
// 遍历数组:使用for...of
for (const item of array) { }

// 遍历对象:使用for...in或Object方法
for (const key in object) { }
Object.keys(object).forEach(key => { });
Object.entries(object).forEach(([key, value]) => { });

// 需要索引:使用for或forEach
for (let i = 0; i < array.length; i++) { }
array.forEach((item, index) => { });

十一、总结 #

本章学习了:

  • for循环的基本用法
  • while和do-while循环
  • for…of遍历可迭代对象
  • for…in遍历对象属性
  • 数组方法替代循环
  • 嵌套循环
  • 实际应用场景

下一章,我们将学习循环控制。

最后更新:2026-03-28