讲解

while 循环只有条件部分:while (条件) { ... },条件为真就一直执行。它适合「不知道要循环多少次,只知道什么时候停」的场景——比如读到文件末尾、等待状态就绪、不断二分逼近答案。do...while 是变体:先执行一次循环体再判断条件,保证至少跑一轮,适合「先做再问要不要继续」的交互逻辑。

while 最大的风险是死循环:条件永远为真,程序卡死。防御方法有三个:确保循环体内有让条件趋向不成立的更新(比如 i++);给循环加上最大轮数兜底(计数器超过阈值就 break);写完循环先想清楚「退出条件是什么、它一定会发生吗」。一个健康的 while 循环,循环体里必然有改变条件所依赖状态的语句。

for 和 while 本质等价,任何 for 都能改写成 while。选择标准是意图表达:循环次数明确(遍历数组、固定次数)用 for;循环次数由运行时状态决定(轮询、逼近、读取流)用 while。把「次数未知」的逻辑硬塞进 for 的三段式里,反而更难读。

示例

// 次数未知的典型场景:不断二分逼近平方根
function sqrtApprox(n) {
  let low = 0;
  let high = n;
  while (high - low > 0.0001) {
    const mid = (low + high) / 2;
    if (mid * mid > n) {
      high = mid;
    } else {
      low = mid;
    }
  }
  return (low + high) / 2;
}
console.log('根号 2 ≈', sqrtApprox(2));

// do...while:至少执行一次
let count = 0;
do {
  count++;
  console.log('第', count, '次尝试');
} while (count < 3);

// 最大轮数兜底,防死循环
let value = 100;
let rounds = 0;
while (value > 1) {
  value = Math.floor(value / 3);
  rounds++;
  if (rounds > 1000) {
    console.log('超过最大轮数,强制退出');
    break;
  }
}
console.log('100 不断除 3 取整,', rounds, '轮后得到', value);

常见坑

  • 循环体里忘记更新状态:while (i < 10) { console.log(i) } 少了 i++ 就是死循环,浏览器标签页直接卡死。
  • 条件里用浮点相等做退出判断:小数累加很难精确等于目标值,退出条件用范围比较(差值小于精度)而不是 ===。
  • do...while 的分号:do { ... } while (条件) 末尾的分号容易漏,虽然多数情况能自动补,但建议显式写上。
  • 把遍历数组写成 while:能用 for...of 就不要手写 while + 下标 + length,多余且易错。

小结

while 处理「条件驱动」的循环,do...while 保证至少一次;循环体必须推进退出条件,必要时加最大轮数兜底。下一节进入最重要的数据结构:数组。