for
循环更复杂一些,但也是最常用的循环。

以下是 for
循环的流程图:
- 初始化(只在第一次循环时执行)
- 条件判断(如果为真,执行循环体;否则退出循环)
- 循环体执行
- 执行迭代器(通常用于更新计数器,如
i++
) - 重复条件判断
上图展示了 for
循环如何按顺序运行。你可以在循环体中放置任何逻辑,而迭代器通常会更新循环控制变量。
语法:
for (begin; condition; step) { // ... loop body ... }
让我们通过一个例子来了解这些部分的含义。下面的循环会对 i
从 0 到 2(不包括 3)执行 alert(i)
:
for (let i = 0; i < 3; i++) { alert(i); }
解释:
-
初始化 (
let i = 0
):初始化变量i
为 0。 -
条件判断 (
i < 3
):每次迭代时检查i
是否小于 3。如果条件为真,执行循环体;如果为假,退出循环。 -
循环体 (
alert(i)
):在每次迭代时弹出i
的值。 -
迭代器 (
i++
):每次循环结束时,i
的值增加 1。
该循环会依次弹出 0
、1
和 2
,三次迭代后退出。
上例for循环语句的算法是这样的:
Run begin → (if condition → run body and run step) → (if condition → run body and run step) → (if condition → run body and run step) → ...
没错,for
循环首先执行一次初始化,然后在每次条件测试后执行循环体和步骤。理解循环如何一步步执行,可以帮助你更好地掌握它的运作方式。
如果你对循环还不太熟悉,回到示例并一步步在纸上模拟它的执行过程可能会很有帮助。
for (let i = 0; i < 3; i++) { alert(i); }
执行过程:
-
初始化:
-
let i = 0;
变量i
被初始化为 0。
-
-
条件测试(第一次):
-
i < 3
,即0 < 3
,条件为true
。 -
循环体执行:
alert(i)
弹出0
。
-
-
步骤更新(第一次):
-
i++
,变量i
增加 1,变成1
。
-
-
条件测试(第二次):
-
i < 3
,即1 < 3
,条件为true
。 -
循环体执行:
alert(i)
弹出1
。
-
-
步骤更新(第二次):
-
i++
,变量i
增加 1,变成2
。
-
-
条件测试(第三次):
-
i < 3
,即2 < 3
,条件为true
。 -
循环体执行:
alert(i)
弹出2
。
-
-
步骤更新(第三次):
-
i++
,变量i
增加 1,变成3
。
-
-
条件测试(第四次):
-
i < 3
,即3 < 3
,条件为false
,循环结束。
-
总结:
-
循环体执行了三次,分别弹出了
0
、1
和2
。 -
循环结束时,
i
为3
,条件不再满足,跳出循环。
通过这样逐步跟踪和模拟,你可以清楚地看到每次循环的执行顺序及其影响。
内联变量声明
在这里,“计数器”变量 i
被直接在循环中声明。这称为“内联”变量声明。这样的变量只在循环内部可见。
for (let i = 0; i < 3; i++) { console.log(i); }
解释:
-
变量
i
被在for
循环的第一部分(初始化部分)内联声明。 -
i
仅在循环体内部有效,循环结束后,i
不再可用。
优点:
-
封闭作用域:
i
的作用域局限于循环内部,不会影响外部代码。 -
避免污染外部作用域:在较大的程序中,避免不小心改变全局变量或其他作用域的变量值。
如果你将 let
或 const
用于循环内的变量声明,它只在循环体中有效,而使用 var
声明的变量则会泄漏到外部作用域,这通常是我们需要避免的行为。
我们也可以不在循环中定义新变量,而是使用一个已有的变量:
let i = 0; for (i = 0; i < 3; i++) { console.log(i); } console.log('循环结束后,i 的值是:', i);
说明:
-
变量
i
是在循环外部定义的。 -
循环中使用的是这个已有的变量。
-
循环结束后,
i
依然存在并可以在外部访问,其值为3
。
这种方式在你需要在循环外部继续使用计数器时很有用。但如果你只需要临时使用一个循环变量,更推荐使用内联声明(for (let i = 0; ...)
),这样变量作用域更清晰、安全。
可以跳过部分语句
for
循环的三个部分(初始化、条件、迭代)中,任何一个都可以被省略。
例如,如果在循环开始时不需要执行任何初始化操作,就可以省略 begin(初始化部分):
示例:
let i = 0; for (; i < 3; i++) { console.log(i); }
说明:
-
初始化部分被省略,但变量
i
已在循环外定义。 -
条件部分
i < 3
照常执行。 -
每次循环后执行
i++
。 -
输出结果是
0
、1
、2
。
类似地,如果你愿意,还可以省略其他部分(条件或迭代器),但要确保逻辑上合理,否则可能会导致无限循环。
我们也可以省略 迭代部分(step):
let i = 0; for (; i < 3;) { console.log(i); i++; // 在循环体内手动更新 }
说明:
-
初始化部分省略(但变量
i
已在外部定义)。 -
条件部分为
i < 3
,正常执行。 -
没有指定迭代器
i++
,所以我们在循环体内部手动执行i++
。
这种写法在你需要更灵活地控制变量更新方式或更新时机时非常有用。只要你自己确保循环变量最终会满足退出条件即可。
我们实际上可以把 for
循环的所有部分都省略,创建一个无限循环:
for (;;) { console.log("循环将永远执行"); }
for (;;) { console.log("循环将永远执行"); }
说明:
-
没有初始化、没有条件、也没有迭代器。
-
条件部分为空,等同于始终为
true
。 -
因此循环永远不会结束,除非你在循环体中使用
break
来显式跳出,或者在某些条件下停止它。
使用 break
停止无限循环
let i = 0; for (;;) { if (i >= 3) break; console.log(i); i++; }
这个版本的无限循环手动控制了退出逻辑,输出 0
、1
、2
,然后停止。
无限循环常用于后台任务、游戏主循环、监听事件等场景,但一定要确保有跳出机制,否则会造成程序卡死。