返回

Object.keys() 和 Object.getOwnPropertyNames() 的异同

前端

探索 JavaScript 中 Object.keys() 和 Object.getOwnPropertyNames() 的区别

在 JavaScript 的广阔世界中,深入了解其核心功能和方法对于成为一名熟练的开发人员至关重要。今天,我们将潜入两个经常被混淆的函数:Object.keys() 和 Object.getOwnPropertyNames()。

关键的区别

这两个函数就像侦探,负责查找并返回对象隐藏的属性。然而,它们的调查范围却大不相同。让我们分解一下它们的关键差异:

  • 目标属性: Object.keys() 仅收集对象的可枚举属性,也就是那些在 for...in 循环中可以访问的属性。而 Object.getOwnPropertyNames() 则囊括了对象的所有自身属性,包括那些不可枚举的和使用 Symbol 值命名的属性。
  • Symbol 属性: Symbol 是 ES6 引入的一种独特数据类型,用来创建独一无二的属性名。Object.keys() 对这些隐蔽的属性视而不见,而 Object.getOwnPropertyNames() 却将其曝光。
  • 原型链属性: 对象的原型链就像一个家族谱系,它包含着从父对象继承的属性。Object.keys() 忽略这些继承属性,而 Object.getOwnPropertyNames() 会将其逐一列出。

代码示例

让我们用代码说明一下这些差异:

// 创建一个对象
const obj = {
  name: 'John Doe',
  age: 30,
  [Symbol('secret')]: 'I am a secret'
};

// 使用 Object.keys() 获取可枚举属性
const keys = Object.keys(obj);
console.log(keys); // ['name', 'age']

// 使用 Object.getOwnPropertyNames() 获取所有自身属性
const propertyNames = Object.getOwnPropertyNames(obj);
console.log(propertyNames); // ['name', 'age', 'Symbol(secret)']

从输出中可以看到,Object.keys() 漏掉了 Symbol 属性,而 Object.getOwnPropertyNames() 则将它们一一呈现。

Symbol 的影响

Symbol 的引入给 Object.keys() 和 Object.getOwnPropertyNames() 带来了一个有趣的转折。由于 Symbol 值是不可枚举的,Object.keys() 无法捕获它们。因此,如果你希望获取对象的完整属性列表,Object.getOwnPropertyNames() 是你的最佳选择。

结论

Object.keys() 和 Object.getOwnPropertyNames() 是两把用于揭示对象秘密的钥匙,它们各有千秋。如果你需要处理可枚举属性,Object.keys() 便捷而高效。但如果你寻求深入挖掘对象的所有属性,包括那些隐蔽的 Symbol 属性,Object.getOwnPropertyNames() 则是你的不二之选。

常见问题解答

  • 问:为什么 Object.keys() 会忽略 Symbol 属性?
    答:因为 Symbol 属性是不可枚举的,而 Object.keys() 只能获取可枚举属性。
  • 问:Object.getOwnPropertyNames() 会返回原型链上的属性吗?
    答:是的,它会返回对象本身和其原型链上的所有属性。
  • 问:我可以修改 Object.keys() 返回的数组吗?
    答:是的,你可以修改它,但它不会影响原始对象的可枚举属性。
  • 问:Object.getOwnPropertyNames() 返回的数组可以排序吗?
    答:是的,你可以使用 sort() 方法对数组进行排序。
  • 问:什么时候应该使用 Object.keys(),什么时候应该使用 Object.getOwnPropertyNames()?
    答:使用 Object.keys() 获取可枚举属性,使用 Object.getOwnPropertyNames() 获取所有自身属性。