讓我們暫時離開個別資料結構,來談談如何反覆運算它們。
在上一章中,我們看到了方法 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…)