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,它们通常比普通对象更适合的数据结构。因此,在您完全控制的代码中,您可能会使用映射而不是对象。但是,作为开发人员,您并不总是可以选择表示形式。有时您操作的数据来自外部 API 或来自某些库函数,这些函数会为您提供对象而不是映射。

Object.entries 使得将对象转换为映射变得容易。

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

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

反过来同样有用:即使您的代码正在使用映射,您可能也需要在某个时候序列化您的数据,例如将其转换为 JSON 以发送 API 请求。或者您可能需要将数据传递给另一个库,该库期望的是对象而不是映射。在这些情况下,您需要根据映射数据创建一个对象。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 支持 #