
文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载导读for与while是 JavaScript 中最常用的两种循环结构它们在语法形态上不同但在语义上可以互相等价转换。本文以《现代 JavaScript 教程》中“用 while 替换 for”这一经典习题为核心系统讲解while、do..while与for三种循环的语法、执行流程与等价改写方法并结合仓库中同章节的系列练习题深入剖析条件检查时机、递增i与i求值顺序等容易踩坑的细节。读完本文你将能够在不改变程序行为的前提下熟练地在for与while之间进行重写并理解两种写法各自的适用场景。一、原题不改变行为地将 for 替换为 while本任务出自 1-js/02-first-steps/13-while-for/5-replace-for-while/task.md题目要求如下重写代码在保证不改变其行为的情况下将for循环更改为while输出应保持不变。待重写的原始代码如下for (let i 0; i 3; i) { alert( number ${i}! ); }这段代码的运行结果是依次弹出number 0!、number 1!、number 2!三条提示。重写时必须保证输出与上述结果完全一致。二、参考答案while 循环的标准改写仓库中 5-replace-for-while/solution.md 给出的标准解法如下let i 0; while (i 3) { alert( number ${i}! ); i; }对照原题与答案可以清晰地看出for循环的三个组成部分是如何被“拆解”到while循环中的for 组成部分原代码重写后的位置begin初始化let i 0循环体外部while之前单独声明condition条件i 3while的条件表达式body循环体alert(...)while的循环体step步进i循环体内部最后一行这就是两者等价转换的核心规则初始化提前到循环外条件原样保留步进移入循环体末尾。行为一致性验证为了确认“输出保持不变”可以逐步展开这段while循环的执行过程let i 0; // 初始化等价于 for 的 begin while (i 3) { // 条件检查i0 → true alert( number 0! ); // 循环体 i; // 步进i 变为 1 } while (i 3) { // 条件检查i1 → true alert( number 1! ); i; // i 变为 2 } while (i 3) { // 条件检查i2 → true alert( number 2! ); i; // i 变为 3 } while (i 3) { ... } // 条件检查i3 → false循环终止每一步都与for循环的执行顺序完全一致先检查条件条件为真则执行循环体再执行步进然后进入下一轮条件检查。三、while 循环语法详解while循环的通用语法如下while (condition) { // 代码 // 所谓的“循环体” }当condition为真时循环体被执行每次循环体的单次执行叫作一次迭代。上面的示例循环共进行了三次迭代。关于while条件有两点需要特别注意依据 article.md条件可以是任意表达式不仅限于比较运算。条件会被计算计算结果会被转化为布尔值。例如while (i ! 0)可以简写为while (i)——当i变成0假值时循环终止let i 3; while (i) { // 当 i 变成 0 时条件为假循环终止 alert( i ); i--; }循环体必须向“终止方向”演进。如果循环体中没有改变条件所依赖变量的语句如上面的i--循环就会理论上无限执行。实际环境中浏览器会提供阻止无限循环的机制服务器端的 JavaScript 则可以通过终止进程来停掉。单行循环体可以省略大括号let i 3; while (i) alert(i--);四、for 循环的结构剖析重写的理论基础要正确完成for → while重写必须先理解for循环的执行算法。for循环的完整语法为for (begin; condition; step) { // ……循环体…… }以for (let i 0; i 3; i) { alert(i); }为例各语句段的作用原文表格如下语句段示例作用beginlet i 0进入循环时执行一次conditioni 3在每次循环迭代之前检查如果为 false停止循环body循环体alert(i)条件为真时重复运行stepi在每次循环体迭代后执行一般循环算法的执行流程可概括为开始运行 → (如果 condition 成立 → 运行 body 然后运行 step) → (如果 condition 成立 → 运行 body 然后运行 step) → ...也就是说begin只执行一次之后每一轮迭代都是“先查条件条件成立则执行循环体再执行步进”。把这段流程逐行展开就是// for (let i 0; i 3; i) alert(i) // 开始 let i 0 // 如果条件为真运行下一步 if (i 3) { alert(i); i } // 如果条件为真运行下一步 if (i 3) { alert(i); i } // 如果条件为真运行下一步 if (i 3) { alert(i); i } // ……结束因为现在 i 3正是由于for的算法是“条件在循环体之前检查、步进在循环体之后执行”它才能被忠实地改写为“条件在while关键字后检查、步进放在循环体末尾”的while循环。变量声明的作用域差异for循环中常见的“内联变量声明”写法for (let i 0; ...)其变量i只在循环内可见for (let i 0; i 3; i) { alert(i); // 0, 1, 2 } alert(i); // 错误没有这个变量而改为while后变量声明被移到循环外部如参考答案中的let i 0;此时i在循环结束后依然可见。如果希望保持“变量不外泄”的语义可以在重写后用块级作用域包裹或者继续沿用for写法。当然for也支持使用外部已存在的变量let i 0; for (i 0; i 3; i) { // 使用现有的变量 alert(i); // 0, 1, 2 } alert(i); // 3可见因为是在循环之外声明的这一作用域差异是两种写法在行为上的唯一实质区别重写时需按实际需求选择。五、从源码层面印证本节的系列练习题“用 while 替换 for”并非孤立题目而是 13-while-for 章节中一系列练习的核心一环。这些练习从不同角度强化了对循环执行顺序的理解可作为本文结论的源码级佐证。1. 循环的最后一个值1-loop-last-value题目考察while (i)配合后缀递减的求值时机solution.mdlet i 3; while (i) { alert( i-- ); }答案为1。alert(i--)先输出当前值、再递减依次显示3、2、1随后i变为0while(i)条件为假循环终止。这验证了条件在每轮迭代之前检查的规则。2. while 循环中的前缀与后缀递增2-which-value-while该题直接对比了i与i在条件中的差异solution.mdlet i 0; while (i 5) alert( i ); // 显示 1、2、3、4 let i 0; while (i 5) alert( i ); // 显示 1、2、3、4、5前缀形式i先递增再参与比较因此i 4时条件实际比较的是5 5循环停止不输出 5后缀形式i用旧值参与比较因此在i 4时条件比较的是4 5为真循环继续执行一次最终输出 5。这个差异正是while重写时“步进语句放在何处”的深层原因步进如果写进条件表达式其求值顺序就会影响行为。3. for 循环中的前缀与后缀递增3-which-value-for与之形成对照的是for循环中i与i结果相同solution.mdfor (let i 0; i 5; i) alert( i ); for (let i 0; i 5; i) alert( i );两种写法都输出0到4。原因是for的step与条件检查是分开的步进返回值未被使用。这说明同样一段逻辑在for中无关紧要的前缀/后缀差异改写为while后可能变得至关重要重写时必须小心处理步进位置。六、扩展do..while 与省略语句段的等价形态do..while条件后置的变体do..while将条件检查移至循环体下面do { // 循环体 } while (condition);它保证循环体至少执行一次。在“重复输入直到正确”类场景中非常实用例如本节 6-repeat-until-correct 的解法solution.mdlet num; do { num prompt(Enter a number greater than 100?, 0); } while (num 100 num);这里两个检查必须同时成立才继续循环num 100表示输入值仍不大于 100 num用于处理用户点击取消num为null或输入空字符串的情况——如果缺少第二次检查null 100为真循环将无法退出。这正是“条件后置 假值判断”的典型用例。省略语句段向 while 的自然过渡for循环的任意语句段都可以省略let i 0; // 变量已在外部声明 for (; i 3; i) { // 省略 begin alert( i ); } let i 0; for (; i 3;) { // 省略 begin 和 step alert( i ); }后一个循环与while (i 3)完全等价——它展示了两者在结构上的同源性省略掉begin和step的for循环本质上就是while循环。也正因如此把for重写为while在语义上始终是安全的。若全部省略则得到无限循环for (;;) { ... }。注意两个分号必须存在否则会出现语法错误。七、循环控制break、continue 与标签完整的循环改写知识还包含控制流指令。当需要提前终止循环时使用breaklet sum 0; while (true) { let value prompt(Enter a number, ); if (!value) break; // (*) sum value; } alert( Sum: sum );“无限循环 break”的组合适用于不必在循环开始或结束时检查条件、而需要在循环体中间进行条件检查的场景。continue则是“轻量版 break”只结束当前迭代、继续下一轮for (let i 0; i 10; i) { if (i % 2 0) continue; // 跳过偶数 alert(i); // 1、3、5、7、9 }当需要从多层嵌套循环中一次性跳出时可以使用标签本节 7-list-primes 的解法solution.mdlet n 10; nextPrime: for (let i 2; i n; i) { // 对每个自然数 i for (let j 2; j i; j) { // 寻找一个除数…… if (i % j 0) continue nextPrime; // 不是素数则继续检查下一个 } alert( i ); // 输出素数 }break labelName可以跳出标记的循环continue与标签配合时跳到标记循环的下一次迭代。需要强调的是break与continue是语句而非表达式不能出现在三元运算符?的右侧否则会产生语法错误。八、总结for 与 while 的等价转换规则回到本文核心任务把for重写为while的可操作步骤如下将for的begin语句初始化提取到while之前执行将for的condition原样作为while的条件表达式将for的循环体搬入while循环体将for的step语句放到while循环体末尾执行。同时记住三条关键结论执行顺序必须保持for是“先查条件、后执行循环体、再步进”while重写必须复现这一顺序因此步进必须放在循环体末尾留意求值差异for的步进返回值不被使用i与i无区别但改写为while后若把递增写进条件表达式前缀与后缀会产生不同行为参见 2-which-value-while作用域不同for内联声明的变量仅循环内可见while重写后变量在循环外声明、循环结束后仍可见必要时需自行处理。通常场景下循环次数明确、结构清晰时优先使用for循环条件本身由外部状态驱动、或需要“先执行再判断”时while与do..while更为自然。掌握两者之间的等价转换是理解 JavaScript 循环本质、写出健壮代码的基础功。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐JavaScript 循环等价改写实战将 for 循环替换为 while 循环zh.javascript.info 练习题精讲JavaScript 循环等价改写实战将 for 循环替换为 while 循环zh.javascript.info 练习题精讲 导读 在 JavaScri文档教程前端JavaScript for 循环改写为 while 循环行为等价的替换实战解析JavaScript for 循环改写为 while 循环行为等价的替换实战解析 本指南以 Modern JavaScript Tutorial 中「Repl文档/教程前端JavaScript 循环结构详解while 和 for 循环JavaScript 循环结构详解while 和 for 循环 在编写脚本时经常需要重复执行相同的操作多次。比如逐个显示列表中的商品或者遍历1到10的数创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考