for...in和for...of的区别

165 阅读3分钟

1. 遍历目标不同

  • for...in
    用于遍历对象的 可枚举属性(包括对象自身的属性和继承的属性)。
    典型场景:遍历普通对象的键(key)。

  • for...of
    用于遍历 可迭代对象(Iterable)的元素值(value)。
    典型场景:遍历数组、字符串、Map、Set、NodeList 等实现了 [Symbol.iterator] 接口的数据结构。


2. 返回值不同

  • for...in
    返回对象的 键(key)。例如,遍历数组时返回索引(字符串形式),遍历对象时返回属性名。

    const obj = { a: 1, b: 2 };
    for (const key in obj) {
      console.log(key); // 输出 'a', 'b'
    }
    
  • for...of
    返回可迭代对象的 值(value)。例如,遍历数组时返回元素值。

    const arr = [10, 20, 30];
    for (const value of arr) {
      console.log(value); // 输出 10, 20, 30
    }
    

3. 适用数据类型不同

  • for...in

    • 适用于普通对象(Object)。
    • 可以遍历数组,但会返回索引(字符串形式,如 '0', '1'),可能引发意外问题(如原型链上的属性)。
  • for...of

    • 适用于实现了 [Symbol.iterator] 的可迭代对象,如:
      • ArrayStringMapSetTypedArray
      • arguments 对象、NodeList(DOM 集合)等
    • 不能直接遍历普通对象(除非手动实现迭代器)。

4. 遍历原型链属性

  • for...in
    会遍历对象自身及原型链上的所有可枚举属性。
    需要使用 hasOwnProperty 过滤:

    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        // 仅处理自身属性
      }
    }
    
  • for...of
    只遍历对象自身的元素,不会涉及原型链。


5. 性能与中断

  • 两者都支持 breakcontinuereturn(在函数中)中断循环。
  • 对于数组遍历,for...of 通常比 for...in 更高效,因为后者需要检查原型链。

代码示例对比

// 遍历数组
const arr = [10, 20, 30];

// for...in:遍历索引(字符串)
for (const index in arr) {
  console.log(index); // '0', '1', '2'
}

// for...of:遍历元素值
for (const value of arr) {
  console.log(value); // 10, 20, 30
}

// 遍历对象
const obj = { a: 1, b: 2 };

// for...in:遍历属性名
for (const key in obj) {
  console.log(key); // 'a', 'b'
}

// for...of:直接报错(普通对象不可迭代)
// for (const value of obj) { ... } // TypeError

总结

  • for...in 遍历对象的键,注意过滤原型属性。
  • for...of 遍历可迭代对象的值(如数组、Map 等)。
  • 避免在数组中使用 for...in(可能引发意外行为)。

回答:首先遍历目标不同,forin是用来遍历对象的可枚举属性也就是遍历的是key,而forof是用来遍历可迭代对象的元素值也就是value。可迭代对象我的理解就是可以遍历的对象。比如遍历数组mapset等的值。

其次也就是返回值不同,刚才说了forin是遍历key,forof是遍历值。

另外就是性能开销不同forin会遍历原型链上所有可枚举属性,而forof只会遍历对象自身的元素,所以说forof更加高效。

另外就是forin使用hasOwnProperty只会遍历对象自身的属性,不会遍历原型链上的属性了。