欢迎光临
我们一直在努力

06 循环:让程序重复干活(for 三段式 · while · break 与 continue · 累加器)

上一篇:05 条件判断:=== 才是正道(if/else · 逻辑连接词 · 三元 · switch)


上篇练习参考答案

练习 1(手动模拟):“1” == 1、“1” === 1、null == undefined、null === undefined、0 == false、0 === false 各得什么? 在这里插入图片描述

"1" == 1 得 true "1" === 1 得 false null == undefined 得 true null === undefined 得 false 0 == false 得 true 0 === false 得 false 六题就是 == 隐式转换的全部把戏——规则没人背得完,所以军规只有一条:写 ===。

练习 2(预测再验证):const x = 0; 之后执行 if (x = 5) { console.log(“A”); } else { console.log(“B”); } 输出什么?x 最后的值变成了多少?为什么? 在这里插入图片描述 会报错:Uncaught TypeError: Assignment to constant variable,因为 x = 5 是把 5 赋予 x 了,而 const 定义的变量不可变!

而当把 const x = 0 改可以重新赋值的 let x = 0 后,输出 "A",且 x 最终变成 5,相当于: x = 5; // 先把 5 赋值给 x if (5) { // 相当于用 if 直接判断 5 ,而 5 在 JavaScript 的布尔判断里是 truthy ,达成 if 条件所以输出A 这就是单个等号的阴险之处:不报错,只换逻辑。 在这里插入图片描述

练习 3(改造要点):给判定器加"旷考"分支——score === -1 表示旷考,等级判为"旷考"、结论判为"需联系教务";注意 else if 的顺序该插在哪(提示:-1 < 60,放最前面判断); score === -1 必须放在最前面——不然 -1 会先命中 score < 60 误判成不及格 正确骨架:

const score = 1;
if (score === 1) {
grade = "旷考";
} else if (score >= 90) {
grade = "优秀";
} else if (score >= 75) {
grade = "良好";
} else if (score >= 60) {
grade = "及格";
} else {
grade = "不及格";
}
console.log(grade);
console.log(`结论:${score === 1 ? "需联系教务" : (score >= 60 ? "平安落地" : "补考")}`);

在这里插入图片描述 结论行用三元的话需要嵌套一层:score === -1 ? "需联系教务" : (score >= 60 ? "平安落地" : "补考")——嵌套三元能写但难读,超过两层就该用 if。

练习 4(疫苗揭晓):现在判定器只能判一个学生。全班 8 个人、8 个分数,难道把判定区复制 8 遍?电脑最擅长的事就是重复——06 篇的循环三行代码判 800 人。动手前先在纸上想:判定区哪些行是"每个学生都要跑一遍"的,哪些行是"全班只需跑一遍"的?(这个思考就是 07 篇函数化的预热。) 每人都要跑的:等级判定链(同样的规则重复用); 全班只跑一次的:报告标题、分隔线。 想清楚"哪些重复、哪些不重复",是写循环前最重要的思考——本篇整篇都在练这件事。


一、场景引入:手写的极限

在这里插入图片描述

把前五篇的三个"手写之痛"摆在一起看:

  • 02 篇:星星树手写 5 行,每行数着空格敲;
  • 03 篇练习:你发现了规律(第 n 层 = repeat(15-n) 空格 + repeat(2n-1) 星),但规律只能装在脑子里,手上还是一行行抄;
  • 05 篇:判定器写好了,可它只认识一个学生。

痛感是同一个:该重复的事,只能靠手复制。循环就是解药——把"重复的规律"交给机器执行。今天学完,星星树改一个数字就能长一百层,报表一秒算完一百年。

二、本篇目标

  • 掌握 for 循环三段式,能把任何"有规律的重复"翻译成循环;
  • 会用 while 处理"条件说了算"的循环,并知道死循环怎么防;
  • 会用 break / continue 两张"逃生券";
  • 掌握累加器模式——以后统计工资、汇总销售额的看家本领。
  • 三、知识点讲解

    3.1 for 循环:三段式

    for (let i = 1; i <= 5; i++) {
    console.log(`${i}`);
    }

    在这里插入图片描述

    圆括号里三个格子,用分号隔开,各管一件事:

    格子代码人话
    起点 let i = 1 计数器从几开始
    终点 i <= 5 到几停(每圈开始前检查,不满足就散场)
    步子 i++ 每圈结束加一(i++ 是 i = i + 1 的简写)

    执行顺序:起点 → 检查终点 → 跑大括号 → 迈步子 → 再检查终点……终点不满足,循环结束。i 就是 03 篇说的"标签",不过是循环自动管理的专用标签——在循环里数数,永远用它,别自己发明。顺带一提:计数器习惯命名为 i、j、k——不是语法规定,是全世界的约定俗成;你这么写,别人读你的代码就一眼能认出"这是个计数器"。

    现在把 03 篇的星星树规律装进来——三行代码,七层树:

    for (let n = 1; n <= 7; n++) {
    console.log(" ".repeat(15 n) + "*".repeat(2 * n 1));
    }

    在这里插入图片描述

    规律进循环,层数随便改:n <= 7 改成 n <= 30,三十层。这就是 03 篇预告的"手写到自动"的跃迁——你负责发现规律,循环负责重复到吐。

    3.2 while:条件说了算的循环

    for 的三段式适合"次数已知"。另一类循环次数未知、条件说了算:倒计时到 0、剩余次数减到 0、温度降到目标值……用 while:

    let fuel = 3;
    while (fuel > 0) {
    console.log(`燃料剩余 ${fuel} 格,继续飞行`);
    fuel; // 千万别忘:条件里动的变量,循环里必须真的动
    }
    console.log("燃料耗尽,弹射!");

    在这里插入图片描述

    结构更简单:while (条件) { 循环体 }——条件真就转一圈再查,假就出门。分工口诀:次数已知用 for,条件说了算用 while。

    死循环警告:while 的条件永远真,页面当场卡死(转圈、点不动)。头号成因就是忘写 fuel–——条件里的变量永远不变,条件永远成立。真卡住了别慌:关掉这个标签页重开就行。写 while 的自检动作只有一条:进循环前问自己"条件里的变量,循环体里谁在改它?"

    3.3 break 与 continue:两张逃生券

    先认识一个小工具:%(取余)——10 % 3 得 1(10 除以 3 余 1)。它最经典的用途是判断倍数:i % 3 === 0 表示"i 是 3 的倍数"。

    两张逃生券(都写在循环体里):

    • break:提前退场。 循环里一撞见它,整个循环立刻终止;
    • continue:跳过这一圈。 撞见它,本轮剩下的代码不跑,直接迈步子进下一圈。

    for (let i = 1; i <= 20; i++) {
    if (i === 13) {
    break; // 撞到 13,整个循环散场
    }
    if (i % 3 === 0) {
    continue; // 3 的倍数跳过不打印
    }
    console.log(i); // 输出 1 2 4 5 7 8 10 11(到 12 的下一圈撞 13 停)
    }

    在这里插入图片描述

    一句话分工:break 是"不干了",continue 是"这个不干,下一个继续"。查找"第一个满足条件的"用 break;过滤"不要某类"用 continue。

    3.4 累加器:统计的看家模式

    编程里一半的循环在干同一件事:把一堆数加起来。固定套路三步:

    let total = 0; // ① 循环外先备一个"账本"(初始 0)
    for (let i = 1; i <= 100; i++) {
    if (i % 2 === 0) { // ② 圈内判断:这笔要不要记
    total += i; // ③ 记账:total = total + i 的简写
    }
    }
    console.log(total); // 1~100 的偶数和

    在这里插入图片描述

    三条纪律:账本必须在循环外用 let 声明(循环内声明 = 每圈换新本子,白记);累加用 += 简写;初始值是 0 不是别的。这个模式以后会反复穿上马甲出场——累计工资、统计销量、汇总账单,骨架全是它。

    顺带认识它的孪生兄弟:累乘器——+= 换 *=、初始值换 1,就能算阶乘(5! = 5×4×3×2×1)。初始值是这套模式最容易翻车的细节:加法账本从 0 起(0 加谁都不变),乘法账本从 1 起(1 乘谁都不变)——乘法账本要是初始化成 0,乘到天荒地老结果还是 0。一句话记住:空账本加法给 0,空账本乘法给 1。

    四、完整实战:批量生成器三件套

    新建 生成器三件套.html,三段实战一次到位:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8">
    <title>批量生成器三件套</title>
    </head>
    <body>
    <h2>批量生成器三件套</h2>
    <p>生成结果在控制台——按 F12 查看。</p>

    <script>
    // ===== 第一件:任意层星星树(改 TREE_FLOORS 就改层数)=====
    const TREE_FLOORS = 7;

    console.log(`生成 ${TREE_FLOORS} 层星星树(for 循环 3 行代码)`);
    for (let n = 1; n <= TREE_FLOORS; n++) {
    console.log(" ".repeat(TREE_FLOORS + 8 n) + "*".repeat(2 * n 1));
    }

    // ===== 第二件:1~100 汇总报表(累加器 × 3)=====
    let sumAll = 0; // 全部之和
    let sumEven = 0; // 偶数之和
    let sumThree = 0; // 3 的倍数之和

    for (let i = 1; i <= 100; i++) {
    sumAll += i;
    if (i % 2 === 0) {
    sumEven += i;
    }
    if (i % 3 === 0) {
    sumThree += i;
    }
    }

    console.log("=".repeat(40));
    console.log(" 1 ~ 100 汇总报表");
    console.log("=".repeat(40));
    console.log(`全部数字之和:${sumAll}`);
    console.log(`偶数之和:${sumEven}`);
    console.log(`3 的倍数之和:${sumThree}`);
    console.log("=".repeat(40));

    // ===== 第三件:倒计时发射(while 条件驱动)=====
    let count = 5;
    while (count > 0) {
    console.log(`倒计时:${count}`);
    count;
    }
    console.log("发射!");

    // ===== 附赠:break 演示——找到第一个 7 的倍数就收工 =====
    for (let i = 100; i <= 200; i++) {
    if (i % 7 === 0) {
    console.log(`100 之后第一个 7 的倍数是 ${i},收工(break)`);
    break;
    }
    }
    </script>
    </body>
    </html>

    看结构:第一件是"规律重复"(for 的主场),第三件是"条件驱动"(while 的主场),第二件是累加器三连——三种循环形态各自站在最擅长的岗位上。

    五、运行效果

    在这里插入图片描述

    生成 7 层星星树(for 循环 3 行代码)
    *
    ***
    *****
    *******
    *********
    ***********
    *************
    ========================================
    1 ~ 100 汇总报表
    ========================================
    全部数字之和:5050
    偶数之和:2550
    3 的倍数之和:1683
    ========================================
    倒计时:5
    倒计时:4
    倒计时:3
    倒计时:2
    倒计时:1
    发射!
    100 之后第一个 7 的倍数是 105,收工(break)

    六、常见报错与排查

    现象 1:页面卡死、转圈点不动(死循环)

    原因:while 条件永远为真——最常见是忘了在循环体里改条件变量(忘写 count–)。 解决:关掉卡死的标签页重开;然后检查 while:条件里动到的变量,循环体里谁在改它? 没人改就是死循环。

    现象 2:星星树只出了 6 层(少一圈)

    原因:终点写成了 n < TREE_FLOORS——n 等于 7 时条件不成立,第 7 圈没跑。< 和 <= 差的那一圈,是"差一错误"(off-by-one)的经典现场。 解决:想清楚"最后一层要不要"——要就 <=,不要就 <。循环边界永远在心里数一遍首尾两个值:n=1 时跑不跑?n=7 时跑不跑?

    报错 3:SyntaxError: Unexpected token(for 那行)

    原因:for 三段之间的分号写成了逗号,或漏了一段(for (let i = 1, i <= 5, i++) 不合法)。 解决:三个格子两根分号,背下来:for (起点; 终点; 步子)。

    排查心法:卡死查步子,少一圈查 <,语法错查分号。循环三大坑一句话打包。

    七、练习作业

  • 手动模拟(先纸上推再回车):for (let i = 10; i > 0; i -= 3) { console.log(i); } 会输出几行?各是什么?(i -= 3 是每圈减 3)
  • 预测再验证:把累加器改成循环内声明——删掉 let sumAll = 0;,在 for 的大括号里第一行写 let sumAll = 0;——报表会输出什么?还是直接报错?(提示:03 篇的老朋友换个地方等你)
  • 改造要点:① 把星星树改成倒三角(最宽的在最上面——提示:让 n 从 TREE_FLOORS 倒着减到 1,想想每层的空格和星号公式怎么变);② 报表加一行"5 的倍数之和";
  • 疫苗(下篇预告):星星树、报表、判定链都写好了,但每段代码只能"当场跑一次"——想在别处再用,只能整段复制粘贴;改一处,两处都得跟着改。07 篇的函数把代码打包成可反复调用的零件:写一次,到处用。先想想:05 篇的判定链如果打包成"输入分数、返回等级"的零件,全班 8 个人的判定会变成什么样?

  • 下一篇预告:《07 函数:把代码打包复用》——参数、返回值、箭头函数,以及"什么时候该抽函数"的判断手感。

    赞(0)
    未经允许不得转载:171主机测评 » 06 循环:让程序重复干活(for 三段式 · while · break 与 continue · 累加器)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址