登录
首页 >  文章 >  前端

Reflect.ownKeys 获取对象所有自有键名(含 Symbol)

时间:2026-05-17 08:13:06 423浏览 收藏

Reflect.ownKeys 是 JavaScript 中唯一能完整获取对象所有自有属性键(包括字符串键和 Symbol 键)的规范方法,它不区分可枚举性,严格按属性创建顺序返回结果,彻底弥补了 Object.keys(仅可枚举字符串键)和 Object.getOwnPropertyNames(仅所有字符串键)在 Symbol 支持上的缺失;但实际使用中需警惕常见陷阱——如 Symbol 必须显式定义在对象自身而非原型上、Symbol.for 仅复用值而非自动挂载、Proxy 会拦截其行为,以及序列化或深拷贝时易意外丢失 Symbol 键——掌握这些细节,才能真正发挥 Reflect.ownKeys 全面、可靠、可预测的核心价值。

如何通过 Reflect.ownKeys 获取包含 Symbol 在内的业务对象所有自有键名

Reflect.ownKeys 能否拿到 Symbol 键?

能,而且这是它和 Object.keysObject.getOwnPropertyNames 最关键的区别:它天然包含所有自有属性键,无论类型是 string 还是 Symbol。如果你发现没拿到 Symbol 键,大概率是因为对象上根本没定义,或者你用的是其他 API 混淆了。

为什么 Object.keys 和 Object.getOwnPropertyNames 都漏掉 Symbol 键?

因为它们的设计目标不同:Object.keys 只返回可枚举的 string 键;Object.getOwnPropertyNames 返回所有 string 键(包括不可枚举的),但明确排除 Symbol;只有 Reflect.ownKeys 是唯一覆盖全部自有键类型的规范方法。

  • Object.keys(obj) → 只有 enumerable string 键
  • Object.getOwnPropertyNames(obj) → 所有 string 键(含不可枚举),但不含任何 Symbol
  • Reflect.ownKeys(obj) → 所有自有键:string + Symbol,顺序按创建顺序(规范保证)

实际使用时要注意哪些坑?

常见误判点不在 API 本身,而在对象构造方式或 Symbol 的可见性。

  • 确保 Symbol 是作为属性键直接定义在对象上,而不是通过原型链继承 —— Reflect.ownKeys 只查自有属性
  • 避免用 Symbol.for('xxx') 时误以为它“全局注册”就等于“自动挂到对象上”,它只是复用 Symbol 值,仍需显式赋值:obj[Symbol.for('id')] = 123
  • 注意 Symbol 描述符(description)为空字符串 Symbol('')Symbol() 是不同的值,调试时容易看花眼
  • 如果业务中用 Proxy 包裹了对象,Reflect.ownKeys 会触发 ownKeys trap,返回值由 trap 决定,不是原始行为

示例:

const symA = Symbol('a');
const symB = Symbol.for('b');
const obj = {
  foo: 1,
  [symA]: 'valueA',
};
obj[symB] = 'valueB';

console.log(Reflect.ownKeys(obj));
// → ['foo', Symbol(a), Symbol(b)](顺序确定,Symbol 按定义顺序出现)

需要过滤或分类键名时怎么处理?

拿到混合数组后,通常要分开 string 和 Symbol 键做不同逻辑。别用 typeof key === 'symbol' 判断 —— 它对 Symbol 键有效,但对字符串键也安全;更稳妥的是用 Symbol.keyFor(key) 检测是否为全局 Symbol,或用 key instanceof Symbol(注意:字面量 Symbol 不是实例,此法仅适用于 Symbol 构造调用,不推荐)。

  • 区分类型:用 key => typeof key === 'symbol' 最简洁可靠
  • 提取所有 Symbol 键:Reflect.ownKeys(obj).filter(k => typeof k === 'symbol')
  • 提取所有字符串键:Reflect.ownKeys(obj).filter(k => typeof k === 'string')
  • 注意:Symbol.keyFor 对匿名 Symbol(如 Symbol('x'))返回 undefined,不能用来判断“是不是 Symbol”
实际业务里最常被忽略的,是误把 Symbol 属性写在原型上、或在深拷贝/序列化流程中丢弃 Symbol 键,导致 Reflect.ownKeys 结果看似“异常”——其实它始终诚实返回当前对象身上的所有自有键。

理论要掌握,实操不能落!以上关于《Reflect.ownKeys 获取对象所有自有键名(含 Symbol)》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>