🧭 前端新手必学:一文看懂 JS 各种遍历方法的区别与用法!
“数组到底该用 for 还是 forEach?”
“对象能不能用 forEach?”
“Map 和 Set 又该怎么遍历?”
对于很多初学者来说,遍历 是最常用却也最容易混淆的知识点。本篇文章将通过对比讲解,带你一次搞清 JavaScript 中各种遍历方法的使用方式、适用对象、优缺点、注意事项!
🧩 一、为什么要学遍历?
遍历是前端开发中最常见的操作之一:
- 渲染列表时需要遍历数据
- 对对象属性做批处理时需要遍历
- 操作 Map、Set、类数组等结构时也要遍历
掌握各种遍历方式,不仅能提升代码质量,还能避免踩坑!
🔁 二、数组的遍历方式对比
方法名 | 是否可中断 | 支持异步 | 修改原数组 | 适用场景 |
---|---|---|---|---|
for | ✅ 是 | ✅ 是 | ✅ 可以 | 所有场景,性能高 |
forEach | ❌ 否 | ❌ 否 | ❌ 不建议 | 常规遍历,代码简洁 |
map | ❌ 否 | ❌ 否 | ❌ 不修改原数组 | 用于“转换”数组 |
for...of | ✅ 是 | ✅ 是 | ❌ | 遍历值 |
for...in | ✅ 是 | ✅ 是 | ❌ | 不推荐遍历数组(会遍历原型链) |
✅ for
循环(老大哥)
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
- ✔ 性能最好,控制力最强
- ✔ 支持
break/continue/return
- ❌ 代码稍啰嗦
✅ forEach
(写法简洁)
arr.forEach((item, index) => {
console.log(item);
});
- ✔ 写法简洁
- ❌ 无法中断循环(break/return 无效)
- ❌ 不支持
async/await
✅ map
(转换新数组)
const newArr = arr.map(item => item * 2);
- ✔ 生成新数组
- ❌ 无法中断,不适合做副作用操作
✅ for...of
(推荐用于数组)
for (const item of arr) {
console.log(item);
}
- ✔ 支持
break/continue
- ✔ 支持异步:可用于
for await...of
- ❌ 无法获取下标(需手动处理)
❌ for...in
(不推荐遍历数组)
for (const key in arr) {
console.log(key, arr[key]);
}
- ❌ 会遍历继承的属性
- ❌ 遍历顺序不一定
- ⚠️ 仅适合遍历对象,不建议用在数组上
🧱 三、对象的遍历方式对比
方法 | 是否遍历原型 | 遍历内容 | 推荐指数 |
---|---|---|---|
for...in | ✅ 是 | key(含原型链) | ⭐ |
Object.keys(obj) | ❌ 否 | 自有 key | ⭐⭐⭐⭐ |
Object.values(obj) | ❌ 否 | 自有 value | ⭐⭐⭐⭐ |
Object.entries(obj) | ❌ 否 | key-value 数组 | ⭐⭐⭐⭐ |
✅ for...in
(可用于对象)
const obj = { a: 1, b: 2 };
for (let key in obj) {
console.log(key, obj[key]);
}
- ⚠️ 会遍历原型链,需搭配
hasOwnProperty
使用
✅ Object.keys
/ Object.entries
Object.entries(obj).forEach(([key, value]) => {
console.log(key, value);
});
- ✔ 安全,只遍历对象自身属性
- ✔ 可与其他遍历组合使用
🗺️ 四、Map & Set 的遍历
✅ Map
const map = new Map([
['name', '小明'],
['age', 18]
]);
for (let [key, value] of map) {
console.log(key, value);
}
✅ Map.forEach
map.forEach((value, key) => {
console.log(key, value);
});
Map 默认按插入顺序遍历,适合做有序的键值对处理。
✅ Set
const set = new Set([1, 2, 3]);
for (let value of set) {
console.log(value);
}
Set 只存值没有键,可用于数组去重后遍历。
🧪 五、类数组/伪数组的遍历
类数组(如 arguments
、NodeList
)可以:
- 转换为数组:
Array.from()
或[...obj]
- 然后使用常规数组遍历方式
const lis = document.querySelectorAll('li');
[...lis].forEach(li => console.log(li.textContent));
🧠 六、如何选择合适的遍历方式?
目标类型 | 推荐遍历方式 |
---|---|
数组 | for , for...of , forEach , map |
对象 | Object.entries , Object.keys |
Map | for...of , forEach |
Set | for...of , forEach |
类数组 | Array.from() + 任意遍历 |
🧨 七、常见误区盘点
❌ forEach
不能使用 break
❌ for...in
不推荐遍历数组
❌ map
不等于 forEach
,返回新数组才用 map
🎯 总结:一图胜千言!
数据结构 → 推荐遍历
-------------------------
数组 → for, forEach, map, for...of
对象 → Object.keys/values/entries
Map → for...of, map.forEach
Set → for...of, set.forEach
类数组 → Array.from(...) → 以上方法
📌 结语
无论你是刚入门的新手,还是已经写了一段时间前端的开发者,熟练掌握各种遍历方式,不仅能提升代码能力,也能写出更优雅、健壮的逻辑处理代码。