在 JavaScript 中,for...of
和 for...in
是两种不同的循环语法,用途和遍历对象有本质区别:
1. for...in
循环
- 用途:遍历对象的可枚举属性(包括自身属性和继承的属性,通过原型链)。
- 遍历的内容:对象的键(key)。
- 适用对象:普通对象(
{}
),但也可以用于数组(不过不推荐,会有问题)。 - 注意事项:
- 会遍历原型链上的可枚举属性,需用
hasOwnProperty
过滤。 - 遍历数组时,返回的是索引(字符串类型),而不是元素值。
- 会遍历原型链上的可枚举属性,需用
const obj = { a: 1, b: 2 };
for (const key in obj) {
if (obj.hasOwnProperty(key)) { // 过滤继承的属性
console.log(key); // 输出 "a", "b"
}
}
// 不推荐用于数组
const arr = [10, 20];
for (const index in arr) {
console.log(index); // 输出 "0", "1"(字符串类型!)
}
2. for...of
循环
- 用途:遍历可迭代对象(Iterable)的值。
- 遍历的内容:可迭代对象的值(value)。
- 适用对象:数组、字符串、
Map
、Set
、TypedArray
、arguments
等实现了[Symbol.iterator]
接口的对象。 - 注意事项:
- 普通对象(
{}
)默认不可迭代,直接使用会报错。 - 需要遍历对象时,需先转换为可迭代结构(如
Object.keys()
)。
- 普通对象(
const arr = [10, 20];
for (const value of arr) {
console.log(value); // 输出 10, 20
}
// 普通对象不可直接遍历
const obj = { a: 1, b: 2 };
// for (const value of obj) { ... } // 报错:obj is not iterable
// 间接遍历对象的方式
for (const key of Object.keys(obj)) {
console.log(obj[key]); // 输出 1, 2
}
总结:如何选择?
- 遍历对象(
{}
):使用for...in
(注意过滤原型属性)。 - 遍历数组、字符串、Map、Set 等可迭代对象:使用
for...of
。 - 普通对象无法用
for...of
,除非手动实现[Symbol.iterator]
接口。
关键区别表
特性 | for...in | for...of |
---|---|---|
遍历内容 | 对象的键(包括继承的) | 可迭代对象的值 |
适用对象 | 普通对象 | 可迭代对象(数组、Map、Set等) |
原型链属性 | 会遍历,需过滤 | 不涉及 |
是否支持普通对象 | 是 | 否(除非自定义迭代器) |
返回值类型 | 字符串(键名) | 任意类型(值) |