for-in循环会遍历对象自身及原型链上所有可枚举属性,需用hasownproperty或object.hasown过滤以确保仅处理自身属性;它不遍历symbol键且顺序不严格。

在 JavaScript 中,for-in 循环会遍历对象自身**以及原型链上所有可枚举的属性**。如果你只想处理对象自身的属性(排除从 Object.prototype 或其他父级原型继承来的属性),就必须用 hasOwnProperty 做过滤。
为什么需要 hasOwnProperty 过滤
for-in 不区分属性来源,只要可枚举、在原型链上,就会被遍历到。比如:
(假设没改过 Object.prototype)
const obj = { a: 1 };<br>for (let key in obj) {<br> console.log(key); // 输出 "a",也可能输出 toString、valueOf 等(如果原型被污染)<br>}
一旦有人给 Object.prototype 添加了可枚举属性(不推荐但可能发生),for-in 就会把它们也列出来。这时 hasOwnProperty 是最可靠的方式判断属性是否属于对象自身。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
正确写法:用 hasOwnProperty 做条件判断
在 for-in 循环体内,对每个 key 调用 obj.hasOwnProperty(key),只处理返回 true 的情况:
- 必须用
obj.hasOwnProperty(key),不能直接写hasOwnProperty(key)(否则可能报错或调用错对象的方法) - 推荐使用
Object.prototype.hasOwnProperty.call(obj, key)更健壮(避免对象自身重写了hasOwnProperty) - ES2022 起也可用
Object.hasOwn(obj, key)—— 它是hasOwnProperty的现代替代,更安全、语义更清晰
三种写法对比(推荐用第三种)
写法一(基础但有风险):
for (let key in obj) {<br> if (obj.hasOwnProperty(key)) {<br> console.log(key, obj[key]);<br> }<br>}
写法二(更安全):
const hasOwn = Object.prototype.hasOwnProperty;<br>for (let key in obj) {<br> if (hasOwn.call(obj, key)) {<br> console.log(key, obj[key]);<br> }<br>}
写法三(推荐,ES2022+):
for (let key in obj) {<br> if (Object.hasOwn(obj, key)) {<br> console.log(key, obj[key]);<br> }<br>}
注意:for-in 本身不保证顺序,且跳过 Symbol 属性
for-in 只遍历字符串键名的可枚举属性,不处理 Symbol 类型的键;遍历顺序在 ES2015 后基本按插入顺序,但对数字索引等仍可能有例外。如果需要严格顺序或包含 Symbol,应改用 Object.keys()、Object.getOwnPropertyNames() 或 Reflect.ownKeys() 配合 for-of。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










