JavaScript基础循环语句共5种:for、while、do...while、for...in、for...of;其中for适用于索引控制强、次数固定或性能敏感场景,需缓存length且避免手动修改循环变量。

JavaScript 循环结构不是“3种”或“7种”的模糊说法——日常开发中真正需要区分、按场景选用的,是 5 种语言级循环语句:for、while、do...while、for...in、for...of。其余如 forEach、map 属于数组方法,不是循环语句;for await...of 是异步迭代特例,暂不纳入基础范畴。
什么时候该用 for?索引控制强、次数固定、性能敏感
当你明确知道要跑多少次(比如遍历 10 个元素)、需要读写特定下标(如修改 arr[i+1])、或对性能有要求时,for 是首选。
- ✅ 推荐写法:缓存
length,避免每次判断都查属性(尤其大数组) - ✅ 支持嵌套,处理二维数组、矩阵等结构很自然
- ❌ 别在循环体里同时用
i++和手动改i(比如i += 2),容易逻辑错乱 - ❌ 别用它遍历普通对象——
for...in才是为此设计的
for (let i = 0, len = arr.length; i < len; i++) {
console.log(arr[i]);
}
while 和 do...while 的核心区别在哪?
while 是「先判后跑」,条件为 true 才进循环;do...while 是「先跑后判」,不管条件如何,循环体至少执行一次。
- ✅
while适合等待状态就绪:比如消费任务队列、轮询接口返回 - ✅
do...while适合强制用户输入、菜单交互等「必须触发一次」的场景 - ⚠️ 两者都极易死循环:务必确保循环体内有改变条件变量的操作(如
tasks.shift()、i++、name = prompt())
let name;
do {
name = prompt('请输入用户名');
} while (!name?.trim());
for...in 和 for...of 到底该谁遍历数组?
for...in 遍历的是「对象的可枚举属性名」(包括原型链上的),顺序不保证,且会遍历到数组方法(如 push、map);for...of 遍历的是「可迭代对象的值」,原生支持数组、字符串、Set、Map(注意:Map 遍历出的是 [key, value] 元组)。
立即学习“Java免费学习笔记(深入)”;
- ✅ 遍历数组元素 → 用
for...of - ✅ 检查对象有哪些字段 / 做浅拷贝 → 用
for...in+hasOwnProperty - ❌ 绝对别用
for...in遍历数组(尤其含自定义属性或扩展了原型时) - ⚠️ 普通对象(如
{a: 1})没有[Symbol.iterator],不能用for...of直接遍历
const arr = [1, 2, 3];
for (const num of arr) {
console.log(num); // 1, 2, 3
}
const obj = { x: 10, y: 20 };
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]); // x 10, y 20
}
}
容易被忽略的坑:死循环、隐式类型转换、Symbol 属性
看似简单的循环,实际藏着几个高频翻车点:
while (i 里忘了i++→ 真·无限卡死,浏览器可能直接无响应- 用
for...in遍历数组时,如果数组原型被污染(比如Array.prototype.last = function(){...}),那个last方法也会被遍历出来 -
for...in完全看不到Symbol属性,得靠Object.getOwnPropertySymbols()单独处理 -
for...of对普通对象报错:TypeError: obj is not iterable,别硬试
循环不是语法练习,是状态推进工具。写之前先问一句:我是在计数?等条件?还是取值?答对了,选哪个循环就基本不会错。











