前端面试题:JS中 for...of 和 for...in 的区别

7 阅读2分钟

在 JavaScript 中,for...offor...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)
  • 适用对象:数组、字符串、MapSetTypedArrayarguments 等实现了 [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...infor...of
遍历内容对象的键(包括继承的)可迭代对象的值
适用对象普通对象可迭代对象(数组、Map、Set等)
原型链属性会遍历,需过滤不涉及
是否支持普通对象否(除非自定义迭代器)
返回值类型字符串(键名)任意类型(值)