Map是停止日常编程中比较常用的数据结构之一。它保留了可以很容易地通过其键来访问的对象键值对。在Java中,用作映射使用HashMap来实现这个目的哈希是很明显的。然而,停止在JavaScript中,对象使用一个普通的用作映射对象来实现这个目标是非常方便的。
但是JavaScript中有一个专门用于此目的的内置数据结构:Map。让我给你一些理由,停止让你喜欢Map而不是对象普通的对象。
1.更多键类型
对象只能有符号(symbols)或字符串。服务器租用用作映射Map可以将任何类型的哈希值作为键:对象,函数或基元(primitives)。停止
const map = new Map(); const myFunction = () => console.log(I am a useful function.); const myNumber = 666; const myObject = { name: plainObjectValue,对象 otherKey: otherValue }; map.set(myFunction, function as a key); map.set(myNumber, number as a key); map.set(myObject, object as a key); console.log(map.get(myFunction)); // function as a key console.log(map.get(myNumber)); // number as a key console.log(map.get(myObject)); // object as a key2.更好地确定大小
Map提供了一个size属性,但一个普通对象的用作映射大小却必须通过艰难的方式来确定。确定Map的大小可以在O(1)时间内完成,而确定一个普通对象的大小则需要O(n)步。
const map = new Map(); map.set(someKey1, 1); map.set(someKey2, 1); ... map.set(someKey100, 1); console.log(map.size) // 100, Runtime: O(1) const plainObjMap = { }; plainObjMap[someKey1] = 1; plainObjMap[someKey2] = 1; ... plainObjMap[someKey100] = 1; console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n)3.更好的性能
对Map进行了优化,以便频繁地添加和删除条目。
此外,Map的条目数可以在恒定的时间内被检索,而一个普通对象的条目数必须被计算,这需要O(n)时间。
以我的Macbook Pro为例,这是一张有1000万个条目的Map的服务器托管平均大小确定时间。
普通JS对象: ~1.6 s Map: < 1 ms此外,它不需要将任何键转换为字符串,这可以节省很多时间。
4.直接迭代
对象必须通过获取键并对其进行迭代。另一方面,Map是可迭代的,这意味着它可以直接迭代。
const map = new Map(); map.set(someKey1, 1); map.set(someKey2, 2); map.set(someKey3, 3); for (let [key, value] of map) { console.log(`${ key} = ${ value}`); } // someKey1 = 1 // someKey2 = 2 // someKey3 = 3 const plainObjMap = { }; plainObjMap[someKey1] = 1; plainObjMap[someKey2] = 2; plainObjMap[someKey3] = 3; for (let key of Object.keys(plainObjMap)) { const value = plainObjMap[key]; console.log(`${ key} = ${ value}`); } // someKey1 = 1 // someKey2 = 2 // someKey3 = 35.key顺序
在ECMAScript 2015之前,一个对象的键不保证以任何特定的顺序出现。在Map上迭代保证键按插入顺序出现。
6.无键覆盖
一个普通对象由于其原型已经包含了一些键,你的键和对象已经包含的键之间可能会有冲突。Map在创建时不包含任何键。
注意:自ECMAScript 2015年起,你可以通过使用 Object.create(null) 来创建你的普通对象图来避免意外的键覆盖。
const map = new Map(); map.set(someKey1, 1); map.set(someKey2, 2); map.set(toString, 3); // No problem for Map const plainObjMap = new Map(); plainObjMap[someKey1] = 1; plainObjMap[someKey2] = 2; plainObjMap[toString] = 3; // Oops, native property