返回

对象属性列表的“诡异”行为

前端

在 JavaScript 的世界中,Object.keys 函数可谓家喻户晓,它能轻易地返回一个数组,其中包含了给定对象所有可枚举属性的名称。然而,这一看似简单的函数却隐藏着一些鲜为人知的“诡异”特性。

枚举属性列表

如前所述,Object.keys 函数返回的对象属性列表是通过遍历该对象的可枚举属性 得来的。这意味着,如果某个属性被标记为不可枚举,它将不会出现在 Object.keys 的结果中。

通常情况下,这正是我们所期望的行为。毕竟,不可枚举属性通常包含内部状态或其他不应公开的信息。然而,在某些情况下,这种行为可能会带来意想不到的后果。

考虑以下代码段:

const obj = {
  foo: 'bar',
  [Symbol('baz')]: 'qux'
};

console.log(Object.keys(obj)); // ['foo']

在这段代码中,我们定义了一个对象,其中包含一个普通属性 foo 和一个使用 Symbol 值作为键的不可枚举属性 [Symbol('baz')]。如你所见,当我们调用 Object.keys 函数时,我们只得到了一个包含 foo 的数组。[Symbol('baz')] 属性被忽略了,因为它不可枚举。

获取所有属性

有时候,我们可能希望获取一个对象的所有 属性,包括不可枚举属性。我们可以使用 Reflect.ownKeys 函数来实现这一目的:

const obj = {
  foo: 'bar',
  [Symbol('baz')]: 'qux'
};

console.log(Reflect.ownKeys(obj)); // ['foo', Symbol(baz)]

如你所见,Reflect.ownKeys 函数返回了一个包含所有属性(包括不可枚举属性)的数组。

遍历所有属性

为了遍历一个对象的所有 属性,无论它们是否可枚举,我们可以使用 for...in 循环:

const obj = {
  foo: 'bar',
  [Symbol('baz')]: 'qux'
};

for (const key in obj) {
  console.log(key); // 'foo'
  console.log(obj[key]); // 'bar'
}

console.log(obj[Symbol('baz')]); // 'qux'

for...in 循环将遍历对象的所有可枚举和不可枚举属性 。然而,它不会 遍历继承的属性。

总结

Object.keys 函数是一个强大的工具,它可以帮助我们获取对象的属性列表。但是,重要的是要了解其行为的限制,尤其是在处理不可枚举属性时。通过使用 Reflect.ownKeys 函数或 for...in 循环,我们可以访问对象的所有 属性,从而获得对其更全面的了解。