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 は、最初の要素がキーで、2番目の要素が値である配列を提供します。

Object.entries は、for-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.

残念ながら、エントリの結果から同等のオブジェクトに戻す簡単な方法はありませんでした…今まで!

Object.fromEntries #

新しい Object.fromEntries API は、Object.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 }

一般的なユースケースの1つは、オブジェクトの変換です。オブジェクトのエントリを反復処理し、既によく知っている配列メソッドを使用することで、変換できるようになりました。

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 }

この例では、長さが 1 のキー、つまりキー xy のみを取得するためにオブジェクトを filter しています。キー abc は取得しません。次に、残りのエントリに対して map を実行し、それぞれに対して更新されたキーと値のペアを返します。この例では、各値を 2 倍することで2倍にしています。最終的な結果は、プロパティが xy のみで、新しい値を持つ新しいオブジェクトです。

オブジェクトとマップ #

JavaScript は Map もサポートしており、これは多くの場合、通常のオブジェクトよりも適切なデータ構造です。したがって、完全に制御できるコードでは、オブジェクトの代わりにマップを使用している場合があります。ただし、開発者として、常に表現を選択できるとは限りません。操作しているデータが外部 API から、またはマップではなくオブジェクトを提供するライブラリ関数から来る場合があります。

Object.entries を使用すると、オブジェクトをマップに簡単に変換できました。

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

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

逆も同様に便利です。コードがマップを使用している場合でも、APIリクエストを送信するためにJSONに変換するなど、データをシリアル化する必要がある場合があります。または、マップではなくオブジェクトを必要とする別のライブラリにデータを渡す必要がある場合もあります。このような場合、マップデータに基づいてオブジェクトを作成する必要があります。Object.fromEntries はこれを簡単に行えます。

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

Object.entriesObject.fromEntries の両方が言語に組み込まれたことで、マップとオブジェクトの間で簡単に変換できるようになりました。

警告:データ損失に注意 #

上記の例のようにマップをプレーンオブジェクトに変換する場合、各キーが一意に文字列化されるという暗黙の前提があります。この前提が満たされない場合、データ損失が発生します。

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 またはその他の手法を使用してマップをオブジェクトに変換する前に、マップのキーが一意の toString 結果を生成することを確認してください。

Object.fromEntries のサポート #