让我们离开各个数据结构,讨论一下如何迭代它们。
在上一章中,我们看到了方法 map.keys()
、map.values()
、map.entries()
。
这些方法是通用的,有一个通用的协议将它们用于数据结构。如果我们创建自己的数据结构,我们也应该实现它们。
它们受以下内容支持
Map
Set
Array
普通对象也支持类似的方法,但语法有点不同。
Object.keys, values, entries
对于普通对象,可以使用以下方法
- Object.keys(obj) – 返回一个键数组。
- Object.values(obj) – 返回一个值数组。
- Object.entries(obj) – 返回一个
[key, value]
对数组。
请注意区别(例如与 map 相比)
Map | 对象 | |
---|---|---|
调用语法 | map.keys() |
Object.keys(obj) ,但不是 obj.keys() |
返回 | 可迭代对象 | “真正的”数组 |
第一个区别是我们必须调用 Object.keys(obj)
,而不是 obj.keys()
。
为什么这样?主要原因是灵活性。请记住,对象是 JavaScript 中所有复杂结构的基础。因此,我们可能有一个像 data
这样的自己的对象,它实现了它自己的 data.values()
方法。我们仍然可以在其上调用 Object.values(data)
。
第二个区别是 Object.*
方法返回“真正的”数组对象,而不仅仅是一个可迭代对象。这主要是出于历史原因。
例如
let user = {
name: "John",
age: 30
};
Object.keys(user) = ["name", "age"]
Object.values(user) = ["John", 30]
Object.entries(user) = [ ["name","John"], ["age",30] ]
以下是如何使用 Object.values
循环遍历属性值的一个示例
let user = {
name: "John",
age: 30
};
// loop over values
for (let value of Object.values(user)) {
alert(value); // John, then 30
}
就像 for..in
循环一样,这些方法忽略使用 Symbol(...)
作为键的属性。
这通常很方便。但是,如果我们也想要符号键,那么有一个单独的方法 Object.getOwnPropertySymbols,它返回一个仅包含符号键的数组。此外,还有一个方法 Reflect.ownKeys(obj),它返回所有键。
转换对象
对象缺少许多数组中存在的方法,例如 map
、filter
等。
如果我们想应用它们,那么我们可以使用 Object.entries
,然后使用 Object.fromEntries
- 使用
Object.entries(obj)
从obj
中获取一个键/值对数组。 - 对该数组使用数组方法,例如
map
,来转换这些键/值对。 - 对结果数组使用
Object.fromEntries(array)
将其转换回对象。
例如,我们有一个包含价格的对象,并希望将其加倍
let prices = {
banana: 1,
orange: 2,
meat: 4,
};
let doublePrices = Object.fromEntries(
// convert prices to array, map each key/value pair into another pair
// and then fromEntries gives back the object
Object.entries(prices).map(entry => [entry[0], entry[1] * 2])
);
alert(doublePrices.meat); // 8
乍一看可能很困难,但使用一两次后就会很容易理解。我们可以通过这种方式创建强大的转换链。
评论
<code>
标记,对于多行,请用<pre>
标记将其包装起来,对于超过 10 行的内容,请使用沙箱 (plnkr、jsbin、codepen…)