在 JavaScript 中,for...in 和 for...of 是两种不同的循环语法,它们的用途和适用场景有明显区别:
1. for...in
-
用途:遍历对象的可枚举属性(包括自身属性和原型链上的属性)。
-
适用对象:普通对象(
Object)。 -
遍历内容:对象的 键(key) ,即属性名。
-
特点:
- 会遍历对象的所有可枚举属性,包括继承的属性(可通过
hasOwnProperty过滤)。 - 遍历数组时,返回的是数组的索引(字符串形式),但可能遍历到非数字属性(如手动添加的属性)。
- 不保证遍历顺序(尤其是对复杂对象)。
- 会遍历对象的所有可枚举属性,包括继承的属性(可通过
const obj = { a: 1, b: 2 };
for (const key in obj) {
console.log(key); // 输出 "a", "b"
}
// 遍历数组(不推荐!)
const arr = [10, 20, 30];
arr.foo = "bar";
for (const index in arr) {
console.log(index); // 输出 "0", "1", "2", "foo"
}
2. for...of
-
用途:遍历可迭代对象(Iterable) 的值。
-
适用对象:数组、字符串、
Map、Set、arguments等实现了Symbol.iterator接口的对象。 -
遍历内容:对象的 值(value) 。
-
特点:
- 直接获取值,无需通过索引访问。
- 不会遍历原型链上的属性。
- 不适用于普通对象(除非对象实现了
Symbol.iterator)。
const arr = [10, 20, 30];
arr.foo = "bar";
for (const value of arr) {
console.log(value); // 输出 10, 20, 30(不会遍历到 "foo")
}
// 遍历字符串
const str = "hello";
for (const char of str) {
console.log(char); // 输出 "h", "e", "l", "l", "o"
}
关键区别总结
| 特性 | for...in | for...of |
|---|---|---|
| 遍历目标 | 对象的可枚举属性名(键) | 可迭代对象的值(value) |
| 适用对象 | 普通对象、数组(不推荐) | 数组、字符串、Map、Set 等可迭代对象 |
| 遍历内容 | 键(字符串) | 值 |
| 原型链属性 | 会遍历 | 不会遍历 |
| 顺序保证 | 不保证(因对象而异) | 按迭代器定义的顺序 |
| 普通对象是否支持 | 支持 | 不支持(除非实现迭代器) |
使用建议
- 遍历对象属性:用
for...in(配合hasOwnProperty过滤原型链属性)。 - 遍历数组或可迭代对象的值:用
for...of。 - 不要用
for...in遍历数组:可能引发意外行为(如遍历到非数字属性)。
// 正确遍历数组
const arr = [1, 2, 3];
for (const value of arr) {
console.log(value); // 1, 2, 3
}
// 正确遍历对象
const obj = { a: 1, b: 2 };
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]); // a 1, b 2
}
}