用Reflect.ownKeys()获取对象所有自有属性(含Symbol与不可枚举)

作者:技术拾光

时间:2026-06-28

浏览:429

在日常的 JavaScript 开发中,经常需要一次性获取对象的所有属性名,尤其是那些隐藏较深的 Symbol 类型或不可枚举属性。ES6 新增的 Reflect.ownKeys() 正是为此而生。 这个静态方法的设计目标非常明确:一次性、无死角地获取对象所有属于自己的属性键名。无论属性键是普通字符

文章目录

在日常的 JavaScript 开发中,经常需要一次性获取对象的所有属性名,尤其是那些隐藏较深的 Symbol 类型或不可枚举属性。ES6 新增的 Reflect.ownKeys() 正是为此而生。

用Reflect.ownKeys()获取对象所有自有属性(含Symbol与不可枚举)

这个静态方法的设计目标非常明确:一次性、无死角地获取对象所有属于自己的属性键名。无论属性键是普通字符串还是 Symbol 类型,无论是否设置了 enumerable: false,只要属性属于对象自身(而非原型链继承),都会被完整列出。

返回顺序遵循规范

Reflect.ownKeys() 返回一个数组,其中键的排列顺序严格按照规范执行:

  • 首先,整数索引(如字符串形式的 '0'、'1')按创建顺序排在最前面。
  • 其次,剩余的普通字符串键按创建顺序排列。
  • 最后,所有的 Symbol 键按创建顺序收尾。

这个顺序与 Object.keys() 等方法保持一致,方便开发者预期结果。

对比同类方法,差异一目了然

为了更清晰理解 Reflect.ownKeys() 的优势,下面将其与几个常用方法进行对比:

  • Object.keys(obj):仅返回可枚举的字符串键,Symbol 键与不可枚举属性均不包含。
  • Object.getOwnPropertyNames(obj):返回所有自有的字符串键,不论是否可枚举,但完全忽略 Symbol 键。
  • Object.getOwnPropertySymbols(obj):专注于所有自有的 Symbol 键,对字符串键无影响。
  • Reflect.ownKeys(obj):集以上方法之大成,返回所有自有键——字符串(含不可枚举)+ Symbol,一步到位。

实例演示:代码一看就懂

在实际编码中,不可枚举属性通常通过 Object.defineProperty 显式创建。下面这个例子展示了 Reflect.ownKeys() 的完整效果:

const sym1 = Symbol('a');
const sym2 = Symbol('b');

const obj = {
  foo: 'bar',
  [sym1]: 'symValue'
};

// 添加一个不可枚举的字符串属性
Object.defineProperty(obj, 'hidden', {
  value: 'secret',
  enumerable: false
});

// 再添加一个不可枚举的 Symbol 属性
Object.defineProperty(obj, sym2, {
  value: 'anotherSym',
  enumerable: false
});

console.log(Reflect.ownKeys(obj));
// 输出:['foo', 'hidden', Symbol(a), Symbol(b)]
//  字符串键(无论是否可枚举)+ Symbol 键(无论是否可枚举)全部列出

输出结果一目了然:foo、hidden、Symbol(a)、Symbol(b) 无一遗漏。

使用注意事项与边界情况

尽管 Reflect.ownKeys() 功能强大,但在使用时仍需注意以下几点:

  • 该方法只处理自有属性,原型链上的公共属性(如 toString()、constructor)不会出现在结果中。
  • 对 null 或 undefined 调用会直接抛出 TypeError,因此调用前建议先进行类型检查,这是良好的编码习惯。
  • 它对普通对象、数组甚至函数均适用。但对于 Math、JSON 等内置全局对象,由于它们自身没有自有属性,调用后返回空数组 []。
  • 该方法只返回属性名列表(钥匙),并不包含属性值。要获取对应值,仍需配合 obj[key] 或 Object.getOwnPropertyDescriptor() 使用。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章