for...in用于遍历对象的可枚举自身及继承属性,需用hasOwnProperty过滤继承属性;不保证遍历顺序,且不适合遍历数组,应选用for...of、forEach或传统for循环。

for...in 用于遍历对象的**可枚举自身属性和继承属性**,但实际使用中需注意它不保证顺序、会遍历原型链上的属性,且不适合遍历数组。
遍历对象自身可枚举属性(推荐加 hasOwnProperty 判断)
默认情况下 for...in 会把对象从原型链上继承来的可枚举属性也列出来。为避免误操作,通常配合 hasOwnProperty() 过滤掉继承属性:
const person = { name: 'Alice', age: 30 };
Object.prototype.city = 'Beijing'; // 添加到原型上(不推荐,仅作演示)
for (let key in person) {
if (person.hasOwnProperty(key)) {
console.log(key, person[key]); // 输出:name Alice,age 30;不会输出 city
}
}
不能依赖遍历顺序
ES2015 之前规范未规定遍历顺序,现代引擎虽对数字键按升序、字符串键按定义顺序处理,但仍不应假设顺序可靠,尤其涉及混合类型键(如 '1'、'a'、Symbol)时:
const obj = { b: 2, 1: 'one', a: 1 };
for (let k in obj) console.log(k); // 实际可能输出:1, a, b(非定义顺序)
别用 for...in 遍历数组
- 它遍历的是“属性名”,不是数组索引,会把数组的额外属性(如
arr.custom = true)和原型方法(如arr.forEach)也列出来 - 遇到稀疏数组(如
arr[10] = 'x')时,会遍历所有中间空槽对应的索引(表现为undefined) - 应改用 for...of、forEach() 或传统 for(let i = 0; i
替代方案更安全(日常建议优先考虑)
- Object.keys(obj):返回自身可枚举属性名数组(不含 Symbol),可配合 for...of 或 map()
- Object.getOwnPropertyNames(obj):包含不可枚举属性(不含 Symbol)
- Object.getOwnPropertySymbols(obj):获取自身 Symbol 属性
- Reflect.ownKeys(obj):返回所有自身属性键(含字符串和 Symbol,且保持定义顺序)


















