for-in遍历对象会包含原型链上可枚举属性,需用Object.prototype.hasOwnProperty.call(obj, prop)过滤;推荐优先使用Object.keys()配合for-of,语义清晰且天然避开原型链。

用 for-in 遍历对象时,默认会遍历对象自身**以及原型链上所有可枚举的属性**,这常导致意外拿到 toString、hasOwnProperty 等内置方法。要避开这些,关键在于**只处理对象自身的属性**。
用 hasOwnProperty 过滤原型链属性
最常用、兼容性最好的方式是配合 hasOwnProperty 方法判断属性是否属于对象自身:
-
obj.hasOwnProperty(prop)返回true仅当prop是obj自身的可枚举属性(不来自原型) - 注意:必须用
Object.prototype.hasOwnProperty.call(obj, prop)更稳妥,防止对象自身重写了hasOwnProperty
示例:
const obj = { name: 'Alice', age: 30 };
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
console.log(key, obj[key]); // 只输出 name 和 age
}
}
改用 Object.keys() + for-of 更清晰安全
Object.keys(obj) 返回的是对象**自身可枚举属性的字符串数组**,天然避开原型链,推荐优先使用:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 语义明确:只关心自身属性,不涉及原型遍历逻辑
- 避免了
for-in的陷阱(比如被修改过的原型、不可枚举但被意外暴露的属性等) - 配合
for-of或forEach写法更现代、易读
示例:
const obj = { name: 'Alice', age: 30 };
for (const key of Object.keys(obj)) {
console.log(key, obj[key]); // 同样只输出 name 和 age
}
注意:for-in 本身不保证遍历顺序,慎用于依赖顺序的场景
for-in 的遍历顺序在 ES2015+ 中对数字键有特殊规则,但总体仍不完全可靠:
- 数字字符串键(如
"1"、"10")会按数值升序排在前面 - 其他字符串键按添加顺序(但受引擎实现影响,旧环境可能不一致)
- 如果需要严格顺序,用
Object.keys()+sort()显式控制
扩展:想遍历包括不可枚举属性?用 Object.getOwnPropertyNames()
如果业务需要访问对象自身的**所有属性(含不可枚举)**,比如调试或序列化:
-
Object.getOwnPropertyNames(obj)返回所有自身属性名(无论是否可枚举) -
Object.getOwnPropertyDescriptors(obj)获取完整描述符,适合深度操作 - 注意:这两者都不包含原型链上的任何属性,天生“安全”

















