const mapToObject = Object.fromEntries(map)
console.log(mapToObject)
// {
// email: "example@yandex.ru",
// url: "https://example.com",
// country: "Russia",
// undefined: undefined,
// NaN: NaN,
// false: true,
// "[object Object]": "мой ключ это объект"
// }
// JavaScript попытался привести последний ключ к строке
// но поскольку он являлся объектом то мы получили "[object Object]"
Map数据结构类似于对象,但有一些关键区别。
让我们通过从一个对象创建一个简单的地图来仔细看看:
卡片是开箱即用的,它们有一个为它们定义的遍历协议,所以我们可以这样做:
我们甚至不需要单独将entry()方法应用于地图,因为它会默认应用。
如果你使用解构,那么隔板会变得更加方便:
仅用于键:
仅值:
地图具有方便的内置方法和属性来使用它们,例如size,它允许您找出特定地图的大小:
如果地图中没有这样的键,get() 方法将通过键或 undefined 返回所需的值:
set()方法,更改或添加新对:
并且使用has()方法,您可以检查是否存在所需的密钥:
完整的方法列表可以在这里查看。
映射中的键不仅可以是字符串或字符(自ECMAScript 2015 起),通常还可以是任何数据类型:
即,如果我们想通过对象键获取值,那么我们需要将相同的对象传递给get() :
让我们使用 Object 类的 fromEntries()方法将我们的地图变回一个对象:
添加新元素时,地图保持秩序(参见上面的控制台示例)。
而且它们的使用需要更多的内存。
如果我没记错的话,主要有两个区别:
对象键只能是字符串和符号(Symbols)。当尝试使用其他数据类型时,它们被强制转换为字符串类型。地图可以有任何数据类型作为键,包括对象。
对象具有原型继承。也就是说,一些键已经预先安装在他们的原型中。如果您将对象用作字典(即在程序执行期间出现任何不可预知的键的数据结构),这可能会造成混淆甚至破坏程序。Map 没有这个,它们从一开始就总是空的,如果你通过它们的 API 向它们添加元素,就不会有破坏某些东西或出现不可预知行为的风险。
还有其他差异。例如,对象更容易序列化、存储、传输和恢复(使用 JSON),它们更适合创建具有特定逻辑和行为的元素(对象具有方法以及方法和数据之间的内部关系)。Maps 更容易获得结构的大小,并且它们支持迭代而无需额外的努力。