Menu

JavaScript for 循环教程:语法、示例、break 与 continue

JavaScript 中经典 for 循环的工作方式:三段式循环头、遍历数组、break 和 continue、嵌套循环,以及常见陷阱。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

经典的 for 循环

当你知道要重复多少次时,for 循环就是合适的工具。它把计数循环的三个部分(起点、终点、步长)都压缩进一行循环头里。

五次迭代,五行输出。来解读一下循环头:

  • let i = 0 在循环开始前运行一次,用来设置计数器。
  • i < 5 在每次迭代前检查。如果为 true,就执行循环体;如果为 false,循环结束。
  • i++ 在每次迭代后运行,紧接着再次检查条件。

这三个部分用分号隔开,而不是逗号。三者都可以省略,但很少有人这么做,那种情况通常会改用 while。

各部分如何配合

手动追踪一次循环,有助于牢记执行顺序:

一步一步来看:

  1. let i = 1:创建计数器并设为 1。
  2. 检查 i <= 3:为 true,执行循环体,打印 1。
  3. 运行 i++:i 现在是 2。
  4. 检查 i <= 3:为 true,打印 2。
  5. 运行 i++:i 现在是 3。
  6. 检查 i <= 3:为 true,打印 3。
  7. 运行 i++:i 现在是 4。
  8. 检查 i <= 3:为 false,退出。

update 步骤在循环体之后运行,而不是之前。这正是很多人容易搞错的地方。

按索引遍历数组

for 循环最常见的用途就是遍历数组。计数器同时充当索引:

有几点值得注意:

  • 数组的索引从 0 开始。第一个元素的索引是 0,最后一个是 length - 1。
  • 条件是 i < fruits.length,而不是 i <= fruits.length。用 <= 会多跑一次,越过末尾并打印出 undefined。
  • i 用 let 声明,所以它的作用域仅限于循环内部。在循环外面,它并不存在。

如果你只需要值而不需要索引,for...of 更短也更清晰,我们会在单独的文档里讲它。

break:提前停止

break 会立即退出循环。当你已经找到要找的东西、不需要继续时,它就很有用:

break 一执行,控制流就会跳到循环的右花括号之后。update 步骤不会运行,条件也不会再检查,循环直接结束。

continue:跳过本次迭代

continue 会跳过当前迭代的剩余部分,直接进入 update 步骤。循环会继续运行,只是不再完成当前这一轮。

偶数会碰到 continue,从而跳过 console.log,只有奇数会被打印出来。当你想过滤掉某些迭代、又不想把循环体的其余部分嵌套进 if 里时,continue 就很方便。

步长不为 +1 的情况

update 步骤只是一个表达式,不一定非得是 i++。每次加 2:

倒着数:

倒序遍历数组,在边遍历边删除元素时有时很有用:

无论选择哪种写法,规则都一样:条件和 update 必须配合起来,让条件最终变为 false。否则循环会一直运行下去。for (let i = 0; i < 10; i--) 就是一个死循环,因为 i 朝错误的方向变化。

嵌套 for 循环

你可以把一个 for 循环放进另一个 for 循环里。外层循环的每一次迭代,内层循环都会完整地运行一遍。

九行输出:外层迭代三次,每次内层迭代三次。给每个计数器起一个有意义的名字(row/col、i/j),不要重复使用同一个变量。

有一点要注意:break 和 continue 只作用于最内层的循环。跳出内层循环并不会停止外层循环。如果需要那样做,可以设置一个标志变量并在外层循环中检查它,或者把嵌套的逻辑提取成一个函数,然后在其中 return。

常见陷阱

几个初学者常踩的坑:

差一错误。 i <= arr.length 会多迭代一次;i < arr.length - 1 会少迭代一次。标准写法是 i < arr.length。

忘记写 update。 如果漏掉了 i++(或类似的语句),计数器永远不变,循环就会一直运行下去:

for (let i = 0; i < 10; ) {
    console.log(i); // never ends
}

用 var 声明计数器。 var 是函数作用域的,所以计数器会泄漏到循环之外,在闭包中引发意想不到的问题。坚持使用 let。

在遍历数组时修改它。 删除元素会让索引移位,导致你跳过某些元素。如果需要删除元素,就倒序遍历,或者用 filter 构建一个新数组。

何时改用其他写法

经典的 for 循环随时可用,但对于常见场景,JavaScript 提供了更简短的选择:

  • 遍历数组的值:for (const item of array) 更简洁。
  • 转换数组:array.map(fn) 返回一个新数组。
  • 筛选:array.filter(fn)。
  • 求和或归约:array.reduce(fn, start)。
  • 只是对每个元素做点什么:array.forEach(fn)。

当你确实需要索引、需要中途跳过或退出,或者需要倒数、每次加 2 这类非标准步长时,再使用经典的 for 循环。

下一步:while 循环

当你事先知道范围时,for 循环最好用。如果不知道,比如想一直运行到某个条件改变为止,while 和 do...while 会更合适。这就是下一页的内容。

常见问题

JavaScript 中 for 循环的语法是什么?

括号里有三个部分,用分号隔开:for (init; condition; update) { ... }。init 只运行一次,condition 在每次迭代前检查,update 在每次迭代后运行。典型的写法是 for (let i = 0; i < 10; i++) { ... }。

JavaScript 中如何遍历数组?

用带索引的经典 for 循环就行:for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }。如果不需要索引,for...of 更简洁:for (const item of arr) { ... }。要转换或筛选数组,通常用 map 和 filter 这类数组方法更合适。

for 循环中的 break 和 continue 是怎样工作的?

break 会立即退出循环,执行跳到循环之后的代码。continue 会跳过当前迭代的剩余部分,直接进入 update 步骤,然后再次检查条件。除非使用标签,否则两者都只作用于最内层的循环。

为什么我的 for 循环停不下来?

通常是 update 步骤从未让条件向 false 靠近。for (let i = 0; i < 10; i--) 会无限循环,因为 i 从 0 开始,只会越来越小。仔细检查条件和 update,它们必须配合起来,让条件最终变为 false。

Coddy 编程语言插图

和 Coddy 一起学编程

开始