Reflect.ownKeys()仅根据属性是否为对象自有来决定返回结果,不受enumerable、writable、configurable等描述符影响,会返回所有自有字符串键和Symbol键。

属性描述符本身 不会影响 Reflect.ownKeys() 的返回结果。
Reflect.ownKeys 只关心“是否存在”,不关心“是否可枚举”
Reflect.ownKeys() 的设计目标就是完整列出对象自身的所有键名——无论该属性是:
- 字符串键还是 Symbol 键
- 可枚举(
enumerable: true)还是不可枚举(enumerable: false) - 可写、可配置与否(
writable/configurable) - 是普通数据属性还是存取器属性(
get/set)
只要这个键是对象“自有”的(即不是从原型链继承来的),它就会被包含在返回数组中。
对比其他方法,更能看清差异
属性描述符中的 enumerable 字段,真正起作用的地方是其他 API:
立即学习“Java免费学习笔记(深入)”;
-
Object.keys():只返回enumerable: true的字符串键 -
Object.getOwnPropertyNames():返回所有字符串键(忽略enumerable,但不包括 Symbol) -
Object.getOwnPropertySymbols():只返回 Symbol 键(同样忽略enumerable) -
Reflect.ownKeys():把上面三类全包了——enumerable对它完全透明
实操验证:不可枚举 + Symbol 都照常出现
看这个例子:
const obj = { a: 1 };
Object.defineProperty(obj, 'b', { value: 2, enumerable: false });
const sym = Symbol('c');
obj[sym] = 3;
console.log(Reflect.ownKeys(obj)); // ['a', 'b', Symbol(c)]
这里 b 是不可枚举的字符串属性,sym 是 Symbol 属性,两者都出现在结果里——说明 enumerable 和 value/get 等描述符字段,对 ownKeys 没有任何过滤作用。
唯一会影响 Reflect.ownKeys 的,是“是否为自有属性”
Reflect.ownKeys() 严格遵循“自有(own)”语义:
- 会包含
Object.defineProperty()添加的属性(无论描述符怎么配) - 不会包含原型上的任何属性(比如
toString、hasOwnProperty) - 对
null或undefined调用会直接报TypeError,和描述符无关
换句话说,决定某个键“出不出现在结果里”的,只有它是不是直接定义在目标对象上,而不是它的描述符长什么样。


















