原文链接:http://javascript.info/keys-values-entries,translate with ❤️ by zhangbao.

让我们远离单个数据结构,并讨论怎样迭代它们。

在之前的章节里,我们有谈论到 map.keys(),map.values() 和 map.entries() 方法。

这些方法是通用的,有一个通用的约定,可以在这些数据结构中使用它们。如果我们创建了自己的数据结构,我们也应该实现它们。

支持的数组结构有:

  • Map

  • Set

  • Array(除了 arr.values() ?)

普通对象也支持类似的方法,但是语法有点不同。

Object.keys,values 和 entries

对普通对象来说,可以使用下面的方法:

  • Object.keys(obj):返回由键名组成的数组。

  • Object.values(obj):返回由键值组成的数组。

  • Object.entries(obj):返回由 [键名, 键值] 对组成的数组。

请注意区别(对比 map 的例子):

Map Object
调用语法 map.keys Object.keys(obj),而不是 obj.keys()
返回 迭代器 “真正”数组

第一点区别是,我们调用形式是 Object.keys(obj),不是 obj.keys()。

为什么要这样呢?主要原因是是为了灵活性。记住,在 JavaScript 中,对象是一切复杂数据结构的基础。我们可能有一个我们自己的对象 order,实现了 order.values() 方法。我们仍然可以在其上调用 Object.values(order) 方法。

第二点不同是,Object* 方法返回的是“真正”的数组,而不是一个迭代器。这主要是由于历史原因。

例如:

  1. let user = {
  2. name: "John",
  3. age: 30
  4. };
  • Object.keys(user) = [name, age]

  • Object.values(user) = [‘John’, 30]

  • Object.entries(user) = [ [‘name’, ‘John’], [‘age’, 30] ]

下面是使用 Object.values 方法循环遍历属性值的例子:

  1. let user = {
  2. name: "John",
  3. age: 30
  4. };
  5. // loop over values
  6. for (let value of Object.values(user)) {
  7. alert(value); // John, 然后是 30
  8. }

Object.keys/values/entries会忽视 Symbol 属性

与 for..in 循环类似,这些方法会忽略 Symbol 类型属性名。

这往往很方便,但是我们想要获得 Symbol 属性值,这里有一个分离的方法 Object.getOwnPropertySymbols() 方法可供使用,它返回由 Symbol 类型的键名(包括不可枚举的)组成的数组。同时,Reflect.ownKeys(obj) 返回由所有类型的键名组成的数组。

也就是说

Object.keys, values 和 entries - 图1

(完)