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

用js刷题的时候,使用for…in遍历一个数组,结果输出的是它的索引?

for...in 遍历的是“键”(Key/Index) for...of 遍历的是“值”(Value)

  • for…in:也就是 “Index”,主要用于对象(Object)的属性遍历。
  • for…of:也就是 “Object Value”,主要用于数组(Array)或可迭代对象的元素遍历。

1. for...in

for...in 是 ES3 就存在的语法。它的设计初衷是遍历对象的可枚举属性

当需要获取一个对象的键名时,它是很好的选择:

const user = {
  name: "tom",
  age: 19
};

for (const key in user) {
  console.log(key); // 输出: "name", "age"
  //以此获取值: user[key]
}

如果用来遍历数组:

  1. 返回的是字符串索引:key 是 “0”, “1” 这样的字符串,而不是数字,进行运算时容易出错。
  2. 顺序不确定:在某些旧浏览器或特定环境下,遍历顺序可能不保证按照数组下标顺序。
  3. 原型链污染:如果数组(或 Array 原型)被添加了自定义属性,for...in 会把它们全都遍历出来。
const colors = ['red', 'blue'];
// 给数组原型加了个方法
Array.prototype.last = function () { return this[this.length - 1]; };

for (const index in colors) {
  console.log(index);
}
// 输出结果:
// "0"
// "1"
// "last"  <-- 连原型上的方法都被遍历出来了!

2. for...of

为了解决 for...in 在数组遍历上的缺陷,ES6 引入了 for...of。它专门用于处理 “可迭代对象”(Iterables),包括数组、字符串、Set、Map 等。不同于 forEach 方法(无法中途跳出循环),for...of 支持所有的循环控制语句:

const scores = [80, 90, 50, 70];

for (const score of scores) {
  if (score < 60) {
    console.log(`发现不及格: ${score},停止检查!`);
    break; // 可以随时终止循环
  }
  console.log(score);
}

总结对比

特性 for…in for…of
关注点 属性名 (Key) 属性值 (Value)
最适合场景 普通对象 (Object) 数组 (Array), 字符串, Set, Map
原型链 遍历原型链属性 (除非用 hasOwnProperty) 不会,只关心集合内的数据
数据类型 键通常被转换为字符串 保持数据的原始类型

建议

  1. 处理数组:首选 for...of(或者 forEachmap)。千万别用 for...in
  2. 处理对象
    • for...in(记得加上 if (obj.hasOwnProperty(key)) 判断)。
    • 推荐 Object.keys(obj)Object.entries(obj) 配合 for...of 来遍历对象,这样更加语义化且安全。