Object.fromEntries
是内置 JavaScript 库中一个有用的补充。在解释它的功能之前,了解预先存在的 Object.entries
API 会有所帮助。
Object.entries
#
Object.entries
API 已经存在一段时间了。
- Chrome: 自版本 54 起支持
- Firefox: 自版本 47 起支持
- Safari: 自版本 10.1 起支持
- Node.js: 自版本 7 起支持
- Babel: 支持
对于对象中的每个键值对,Object.entries
会返回一个数组,其中第一个元素是键,第二个元素是值。
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.
不幸的是,没有简单的方法可以从 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
的键,即仅 x
和 y
键,而不是 abc
键。然后,我们对剩余的 entries 进行 map
操作,并为每个 entries 返回一个更新的键值对。在这个例子中,我们将每个值乘以 2
来加倍。最终结果是一个新对象,只有 x
和 y
属性,以及新的值。
对象与映射 #
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.entries
和 Object.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
支持 #
- Chrome: 自版本 73 起支持
- Firefox: 自版本 63 起支持
- Safari: 自版本 12.1 起支持
- Node.js: 自版本 12 起支持
- Babel: 支持