<p>Object.getOwnPropertyNames 返回对象自身所有字符串键自有属性名(含不可枚举),不包括原型链属性、Symbol 键及 # 私有字段;它无法获取所谓“私有属性”,因后者在语言层面禁止反射访问。</p>

JavaScript 中没有真正意义上的“私有属性”,Object.getOwnPropertyNames 无法获取所谓“私有属性”,它只能枚举对象**自身所有可枚举和不可枚举的自有属性名(字符串)**,但不包括原型链上的属性,也不包括用 # 语法定义的真私有字段(Private Fields)。
Object.getOwnPropertyNames 能拿到什么?
它只返回目标对象**自己拥有的**属性键(包括不可枚举的,如 constructor、toString 等),但:
- ❌ 不会遍历原型链(所以不会返回原型对象上的属性)
- ❌ 不会返回 Symbol 类型的属性(要用
Object.getOwnPropertySymbols) - ❌ 完全无法访问
#field这类私有字段——它们在语言层面被禁止反射访问 - ✅ 可以看到通过
Object.defineProperty(obj, 'x', { enumerable: false })设置的不可枚举自有属性
为什么不能从原型对象“获取私有属性”?
两个关键原因:
-
原型上的属性不是“私有”的:比如
Array.prototype.map是公开可读、可调用的方法,只是不在实例自身上,需靠原型链访问;getOwnPropertyNames明确跳过原型链,所以根本拿不到 -
ES2022 的 # 私有字段不可反射:它们在运行时完全隔离,连
in、hasOwnProperty、Reflect.ownKeys都看不到,Object.getOwnPropertyNames同样无能为力
想查原型上的自有属性?得手动指定原型对象
如果你真想查看某个原型对象(比如 Array.prototype)自身有哪些属性,可以把它当作普通对象传入:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
const proto = Array.prototype; console.log(Object.getOwnPropertyNames(proto)); // → ['length', 'constructor', 'toString', 'toLocaleString', 'join', 'pop', ...]
注意:这拿到的是 Array.prototype 自己的属性,不是某个数组实例的,更不是“私有”的。
那真正的私有字段怎么办?
用 # 声明的字段(如 class C { #x = 1; }):
- 设计初衷就是不可探测、不可枚举、不可反射
- 任何
Object.*方法、for...in、Reflect.*都无法访问 - 唯一操作方式:在同一个类的内部方法中通过
this.#x访问
不复杂但容易忽略:所谓“私有”,首先是语言机制保障的不可见性,不是靠命名约定或闭包隐藏——后者还能被调试器或 console.dir 碰运气看到,而 # 字段是彻底屏蔽的。

















