reflect.ownkeys() 返回对象所有自有属性键名(含可枚举/不可枚举字符串键及所有symbol键),而object.keys()仅返回可枚举字符串键,object.getownpropertynames()返回所有字符串键但不含symbol。

Reflect.ownKeys() 是获取对象所有**自有属性键名**(包括字符串和 Symbol 类型)的标准方法,它返回一个数组,包含该对象自身拥有的、可枚举和不可枚举的所有属性键(不含原型链上的属性)。
它和 Object.keys()、Object.getOwnPropertyNames() 有什么区别?
三者都只查对象自身的属性(不查原型),但覆盖范围不同:
- Object.keys():只返回可枚举的字符串键(忽略 Symbol 和不可枚举属性)
- Object.getOwnPropertyNames():返回所有字符串键(含不可枚举的,但不包括 Symbol)
- Reflect.ownKeys():返回所有自有键,即字符串键 + Symbol 键(无论是否可枚举)
基本用法示例
假设有一个对象同时定义了字符串属性和 Symbol 属性:
const sym1 = Symbol('a');
const sym2 = Symbol('b');
const obj = {
foo: 1,
bar: 2
};
Object.defineProperty(obj, 'hidden', {
value: 3,
enumerable: false
});
obj[sym1] = 'symbol-value-1';
obj[sym2] = 'symbol-value-2';
console.log(Reflect.ownKeys(obj));
// ['foo', 'bar', 'hidden', Symbol(a), Symbol(b)]
可以看到,结果完整包含了:
– 可枚举字符串键(foo、bar)
– 不可枚举字符串键(hidden)
– 所有 Symbol 键(Symbol(a)、Symbol(b))
实际开发中怎么用?
常见于需要“完整遍历对象自有结构”的场景,比如:
- 深克隆或序列化工具:确保 Symbol 属性也被复制或保留
-
代理(Proxy)拦截:配合
ownKeystrap 实现自定义键枚举逻辑 -
调试/检查对象结构:比
Object.keys()更全面地看清对象真实键集
例如在 Proxy 中重写 ownKeys 行为:
const handler = {
ownKeys(target) {
console.log('Reflect.ownKeys 被调用');
return Reflect.ownKeys(target).filter(key => typeof key !== 'symbol'); // 过滤掉 Symbol
}
};
const proxy = new Proxy({ a: 1, [Symbol('x')]: 2 }, handler);
console.log(Object.getOwnPropertyNames(proxy)); // ['a'] —— Symbol 被过滤
注意点
– 它不返回原型链上的属性,这点和 for...in 不同
– 返回顺序是:先字符串键(按创建顺序,含不可枚举),再 Symbol 键(按添加顺序)
– 如果目标不是对象(如 null、原始值),会抛出 TypeError
– 它是 Object.getOwnPropertyNames() + Object.getOwnPropertySymbols() 的等价组合,但更简洁统一
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











