引言
在 JavaScript 中,遍历数组和对象是常见的操作,而我们有多种方式来进行这些遍历,比如 for of、for in、forEach 和map。你能搞懂他们之间的区别吗?本文将详细介绍它们的区别和使用场景。
1. for in:遍历对象的属性(包括继承的属性)
for in 循环用于遍历对象的可枚举属性 。这包括对象的自身属性和继承自原型链的属性。
特点:
- for in 会遍历对象的所有可枚举属性(包括继承的属性)。
- 它适用于对象,但不适用于数组,因为数组有索引,且数组本身也是对象,索引可能是对象的属性,for in 会不按顺序遍历数组。
- 可能会遍历到对象继承的属性。
示例:
| 12
 3
 4
 5
 6
 7
 
 | const person = {name: 'wyx',
 age: 27
 };
 for (let key in person) {
 console.log(key, person[key]);
 }
 
 | 
注意事项:
- 使用 for in 时,建议使用 hasOwnProperty 方法来检查属性是否是对象自身的属性,避免遍历到继承的属性:
| 12
 3
 4
 5
 
 | for (let key in person) {if (person.hasOwnProperty(key)) {
 console.log(key, person[key]);
 }
 }
 
 | 
2. for of:遍历可迭代对象(数组、字符串、Map、Set)
for of 循环是用于遍历任何可迭代对象 (如数组、字符串、Map、Set 等)。它会逐一返回每个元素的值。
特点:
- 只适用于可迭代对象 (如数组、字符串、Map、Set)。
- 返回的是元素的值,而不是键(索引或属性名)。
- for of 不会遍历对象的属性,它仅遍历数组或其他可迭代对象的元素。
示例:
| 12
 3
 4
 5
 
 | const arr = [10, 20, 30];
 for (let value of arr) {
 console.log(value);
 }
 
 | 
3. forEach:数组的迭代方法
forEach 是数组的内置方法,用于遍历数组元素。它接收一个回调函数,遍历数组时会逐个执行该回调函数。
特点:
- 只适用于数组。
- 回调函数接受三个参数:当前元素的值、当前元素的索引、原数组本身。
- 不支持中途跳出(无法使用 break或return来退出循环)。
示例:
| 12
 3
 4
 5
 
 | const arr = [1, 2, 3];
 arr.forEach((value, index, array) => {
 console.log(value, index);
 });
 
 | 
注意事项:
- forEach 不支持 break 和 continue 语句来控制循环的中断或跳过。
- 如果需要在遍历过程中跳出,可以考虑使用 for of 或其他手段。
4. map:返回新的数组
map 方法用于创建一个新数组,数组的每一项是原数组元素经过指定回调函数处理后的结果。
特点:
- 只适用于数组。
- 会返回一个新的数组,不会改变原数组。
- 回调函数可以接受三个参数:当前元素的值、当前元素的索引、原数组本身。
- map 方法会遍历整个数组并返回一个新数组,因此通常用于转换数组中的元素。
示例:
| 12
 3
 4
 5
 
 | const arr = [1, 2, 3];
 const doubled = arr.map(value => value * 2);
 
 console.log(doubled);
 
 | 
注意:
- map 会返回一个新的数组,而不是修改原数组。
- 如果你只想遍历并不需要返回新的数组,使用 forEach 或其他方式可能更合适。
总结
| 方法 | 用途 | 遍历对象 | 是否修改原数组 | 是否返回新数组 | 是否可以跳出循环 | 适用场景 | 
| for in | 遍历对象的属性 | 对象的属性 | 否 | 否 | 可以(使用 break) | 对象的属性遍历 | 
| for of | 遍历可迭代对象的值 | 数组、字符串、Map、Set 等 | 否 | 否 | 可以(使用 break) | 数组、字符串、Set、Map 等的遍历 | 
| forEach | 数组遍历 | 数组的元素 | 否 | 否 | 不可以 | 数组的遍历 | 
| map | 返回一个新数组 | 数组的元素 | 否 | 是 | 不可以 | 数组元素的转换 | 
如何选择
- 如果需要遍历对象的属性 ,使用 for in(需注意继承的属性)或Object.keys()配合for of。
- 如果需要遍历数组或可迭代对象的元素 ,使用 for of。它简洁且能准确处理数组元素。
- 如果需要在遍历过程中做一些操作而不改变原数组 ,使用 forEach,但请注意它无法中途跳出。
- 如果你需要通过映射操作生成一个新的数组 ,使用 map,因为它返回一个新的数组。