讲解
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 保证至少一次;循环体必须推进退出条件,必要时加最大轮数兜底。下一节进入最重要的数据结构:数组。