object.keys()只返回对象自有可枚举属性名,不遍历原型链;for...in会遍历原型链,需用hasownproperty()区分继承属性;验证自有属性推荐object.keys().includes()、hasownproperty()或propertyisenumerable()。

Object.keys() 本身不涉及原型链,它天然只返回对象“自有”的可枚举属性名,完全忽略原型链上的任何属性。所以你不需要、也不应该用原型链去“配合”它来获取自有属性——它已经自动做到了这一点。
Object.keys() 自动过滤原型链
它内部机制就是只检查对象自身的属性描述符(own property descriptors),不向上遍历 __proto__ 或 Object.getPrototypeOf() 链。这意味着:
- 即使父对象有一个可枚举属性
name,子对象没重写它,Object.keys(child)也不会包含"name" - 第三方库往
Object.prototype上挂的方法(比如Object.prototype.each),对Object.keys()完全透明,不会被列出 - 它和
for...in的关键区别就在这里:for...in会进原型链,Object.keys()不会
想查原型链上的可枚举属性?不用 Object.keys()
如果你确实需要获取原型链上(包括自身)所有可枚举属性名,得手动遍历原型链:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 用
for...in循环 +hasOwnProperty()判断是否为继承属性 - 或写递归:从目标对象开始,依次调用
Object.getPrototypeOf(),对每一层调用Object.keys()并合并结果(注意去重) - 但注意:
Object.keys()在每一层仍只取该层的自有可枚举键,不是帮你“穿透”原型链的工具
验证自有属性的正确方式
确认某个 key 是对象自身的(而非继承的),推荐组合使用:
-
Object.keys(obj).includes(key)→ 表明它是自有且可枚举的 -
obj.hasOwnProperty(key)→ 表明它是自有属性(无论是否可枚举) -
Object.prototype.propertyIsEnumerable.call(obj, key)→ 表明它在当前对象上是可枚举的
什么时候需要关心原型链?
通常只有两种情况:
- 你想做“深度键提取”,比如把一个实例及其所有原型上的可枚举属性名都收集起来(这时
Object.keys()单独不够,需配合getPrototypeOf) - 你在调试时发现
for...in多出了意外的 key,想排查是否来自原型污染——此时对比Object.keys(obj)和for...in的输出,就能快速定位问题来源
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










