很多人第一次看到“循环嵌套”,脑子里就冒出一堆问号:外层循环跑一次,内层是不是要跑完一圈?两个for套一起,到底谁先动、谁等谁?其实没那么玄乎,咱们拿做饭和打印表格来说。
先看个生活例子:炒一盘青椒肉丝
你得切肉丝、切青椒、倒油、热锅、下肉、翻炒、下青椒、再翻炒、加盐、出锅……但要是今天要做3盘呢?
你不会把所有肉全切完、再统一炒3次——更可能是:每盘都按完整步骤来一遍。也就是:第1盘→切+炒;第2盘→切+炒;第3盘→切+炒。
这里,“做几盘”是外层动作,“每盘的完整流程”是内层动作。外层决定重复几次,内层负责每次具体干啥。
再看代码里怎么写
比如打印一个 3 行 × 4 列的星号方阵:
for (let i = 0; i < 3; i++) { // 外层:控制行数,跑3次
let row = '';
for (let j = 0; j < 4; j++) { // 内层:控制每行几个星号,每次跑4次
row += '*';
}
console.log(row); // 打印这一行
}运行结果是:
****
****
****注意:外层变量 i 每变一次,内层 j 就从 0 跑到 3 完整一遍。也就是说,i=0 时,j 跑了 0→1→2→3;i=1 时,j 又从 0 开始跑一遍……不是 j 一直累加到 12。
经典实战:九九乘法表
为什么它非得用嵌套?因为每一行的算式个数不一样:第1行1个(1×1),第2行2个(2×1、2×2),第3行3个……直到第9行9个。
外层控制“当前是第几行”(i 从 1 到 9),内层控制“这行要算几个”(j 从 1 到 i):
for (let i = 1; i <= 9; i++) {
let line = '';
for (let j = 1; j <= i; j++) {
line += `${j}×${i}=${i*j} `;
}
console.log(line);
}你会发现,内层循环的结束条件依赖外层变量(j <= i),这是嵌套常用手法——让内层“听外层的”。
一个小提醒
嵌套别太深。三层以上(for 里套 for 再套 for)就容易绕晕,也难调试。真遇到复杂逻辑,不妨拆成函数,让每层只干一件小事,反而更稳。