Object.fromEntries

發佈於 · 標籤為 ECMAScript ES2019

Object.fromEntries 是內建 JavaScript 函式庫中一個有用的新增功能。在說明其功能之前,先了解現有的 Object.entries API 會有所幫助。

Object.entries #

Object.entries API 已存在一段時間了。

  • Chrome: 自版本 54 起支援
  • Firefox: 自版本 47 起支援
  • Safari: 自版本 10.1 起支援
  • Node.js: 自版本 7 起支援

對於物件中的每個鍵值對,Object.entries 會提供一個陣列,其中第一個元素是鍵,第二個元素是值。

Object.entriesfor-of 結合使用時特別有用,因為它能讓您非常優雅地反覆處理物件中的所有鍵值對

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

for (const [key, value] of entries) {
console.log(`The value of ${key} is ${value}.`);
}
// Logs:
// The value of x is 42.
// The value of y is 50.

很遺憾的是,沒有簡單的方法可以從 entries 結果返回到等效的物件…直到現在!

Object.fromEntries #

新的 Object.fromEntries API 執行與 Object.entries 相反的動作。這使得根據物件的 entries 重建物件變得容易

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

const result = Object.fromEntries(entries);
// → { x: 42, y: 50 }

一個常見的用例是轉換物件。現在,您可以透過反覆處理其 entries,然後使用您可能已經熟悉的陣列方法來執行此動作

const object = { x: 42, y: 50, abc: 9001 };
const result = Object.fromEntries(
Object.entries(object)
.filter(([ key, value ]) => key.length === 1)
.map(([ key, value ]) => [ key, value * 2 ])
);
// → { x: 84, y: 100 }

在此範例中,我們使用 filter 篩選物件,只取得長度為 1 的鍵,也就是只有鍵 xy,但沒有鍵 abc。然後,我們對剩下的 entries 使用 map,並為每個 entries 傳回更新的鍵值對。在此範例中,我們將每個值乘以 2,將其加倍。最終結果是一個新的物件,只包含屬性 xy,以及新的值。

物件與映射 #

JavaScript 也支援 Map,這通常比一般物件更適合作為資料結構。因此在完全由你控制的程式碼中,你可能會使用 map 取代物件。然而,作為開發人員,你並非總是能選擇表示形式。有時你操作的資料來自於外部 API 或某些函式庫函式,而這些函式庫函式提供給你的是物件,而不是 map。

Object.entries 讓物件轉換成 map 變得容易

const object = { language: 'JavaScript', coolness: 9001 };

// Convert the object into a map:
const map = new Map(Object.entries(object));

反過來也同樣有用:即使你的程式碼使用 map,你可能需要在某個時間點序列化你的資料,例如將其轉換成 JSON 以發送 API 要求。或者你可能需要將資料傳遞給預期物件而非 map 的其他函式庫。在這些情況下,你需要根據 map 資料建立一個物件。Object.fromEntries 讓這變得非常簡單

// Convert the map back into an object:
const objectCopy = Object.fromEntries(map);
// → { language: 'JavaScript', coolness: 9001 }

有了 Object.entriesObject.fromEntries 這兩個語言中的函式,你現在可以輕鬆地在 map 和物件之間進行轉換。

警告:小心資料遺失 #

在將 map 轉換成純粹物件時,如同上述範例,有一個隱含的假設,即每個金鑰都唯一地字串化。如果這個假設不成立,就會發生資料遺失

const map = new Map([
[{}, 'a'],
[{}, 'b'],
]);
Object.fromEntries(map);
// → { '[object Object]': 'b' }
// Note: the value 'a' is nowhere to be found, since both keys
// stringify to the same value of '[object Object]'.

在使用 Object.fromEntries 或任何其他技術將 map 轉換成物件之前,請確保 map 的金鑰會產生唯一的 toString 結果。

Object.fromEntries 支援 #