Reflect.ownKeys能获取对象自身所有类型属性键(字符串和Symbol),顺序严格遵循ECMAScript规范:先整数索引、再其他字符串键、最后Symbol键,且不触发getter等副作用,与Proxy.ownKeys拦截器兼容。

Reflect.ownKeys 能拿到对象自身所有类型的属性键(包括字符串、Symbol),且顺序更可靠,比 Object.keys 和 Object.getOwnPropertyNames 更完整、更中立。
覆盖所有自有属性类型
它不区分属性名的类型,一次性返回字符串键和 Symbol 键。而 Object.keys 只返回可枚举的字符串键,Object.getOwnPropertyNames 只返回字符串键(含不可枚举的),都不包含 Symbol。
-
Object.keys({a:1, [Symbol('b')]:2})→['a'] -
Object.getOwnPropertyNames({a:1, [Symbol('b')]:2})→['a'] -
Reflect.ownKeys({a:1, [Symbol('b')]:2})→['a', Symbol(b)]
保持标准定义的遍历顺序
返回结果严格遵循 ECMAScript 规范中的属性枚举顺序:先按创建顺序排列的整数索引(如 '0'、'1'),再按创建顺序的其他字符串键,最后按创建顺序的 Symbol 键。这种可预测性在需要稳定序列的场景(比如深克隆、序列化、代理拦截)中很关键。
- 对象
{'2':1, b:2, '0':3, [Symbol('s')]:4, '1':5}的Reflect.ownKeys结果是['0', '1', '2', 'b', Symbol(s)] - 其他方法不保证该顺序,尤其对数字字符串键的处理较随意
与 Proxy 拦截行为一致
Proxy 的 ownKeys 拦截器必须返回一个数组,其内容和格式需与 Reflect.ownKeys 的返回值兼容。用它作为默认实现或校验依据,能避免陷阱——比如返回非数组、含重复项、漏掉不可枚举属性等,都会导致 Proxy 报错。
立即学习“Java免费学习笔记(深入)”;
- 在 Proxy handler 中直接
return Reflect.ownKeys(target)是安全、推荐的做法 - 若手动拼接键,容易遗漏 Symbol 或破坏顺序,引发难以调试的问题
不触发副作用,行为纯粹
它只读取属性键列表,不会访问属性值,也不调用 getter,不触发任何副作用。相比之下,for...in 或 Object.keys 在某些边界情况下(如带 getter 的原型链)可能意外触发逻辑,而 Reflect.ownKeys 始终只看自身、只看键名、只看定义本身。
- 即使对象某个属性的 getter 会报错或发请求,
Reflect.ownKeys也完全不受影响 - 适合在冻结对象、审计结构、生成元信息等“只看结构不碰值”的场景使用










