我刚刚发现了这个特点:
Map: Map对象是简单的键/值映射。
这让我很困惑。常规JavaScript对象是字典,那么Map与字典有什么不同呢?从概念上讲,它们是相同的(根据Stack Overflow的另一个问题)
文档也没有帮助:
Map对象是键/值对的集合,其中键和值都可以是任意的ECMAScript语言值。不同的键值只能出现在Map集合中的一个键/值对中。使用创建Map时选择的比较算法进行区分的不同键值。
Map对象可以按插入顺序迭代其元素。Map对象必须使用哈希表或其他机制来实现,这些机制提供的访问时间平均与集合中元素的数量呈次线性关系。本Map对象规范中使用的数据结构仅用于描述Map对象所需的可观察语义。它并不是一个可行的实现模型。
听起来还是像个物件,显然我错过了什么。
为什么JavaScript获得一个(受良好支持的)Map对象?它能做什么?
除了其他答案之外,我还发现map比对象操作起来更笨拙和冗长。
obj[key] += x
// vs.
map.set(map.get(key) + x)
这一点很重要,因为较短的代码读起来更快,表达更直接,并且更好地记在程序员的脑海里。
另一方面:因为set()返回的是映射,而不是值,所以不可能链式赋值。
foo = obj[key] = x; // Does what you expect
foo = map.set(key, x) // foo !== x; foo === map
调试地图也更加痛苦。下图中,你实际上看不到地图中的键是什么。你必须编写代码才能做到这一点。
对象可以被任何IDE计算:
我认为到目前为止答案中还没有提到以下几点,我认为它们值得一提。
地图可以更大
在Chrome中,我可以使用Map获得1670万个键/值对,而使用常规对象可以获得1110万个键/值对。带地图的情侣数量几乎增加了50%。它们在崩溃前都占用了大约2gb的内存,所以我认为可能与chrome的内存限制有关(是的,尝试填充2个地图,在崩溃前你只能得到830万对)。你可以用下面的代码自己测试它(显然,分开运行它们,而不是同时运行):
var m = new Map();
var i = 0;
while(1) {
m.set(((10**30)*Math.random()).toString(36), ((10**30)*Math.random()).toString(36));
i++;
if(i%1000 === 0) { console.log(i/1000,"thousand") }
}
// versus:
var m = {};
var i = 0;
while(1) {
m[((10**30)*Math.random()).toString(36)] = ((10**30)*Math.random()).toString(36);
i++;
if(i%1000 === 0) { console.log(i/1000,"thousand") }
}
对象已经有了一些属性/键
这个问题以前让我犯过错误。常规对象有toString, constructor, valueOf, hasOwnProperty, isPrototypeOf和其他一堆预先存在的属性。对于大多数用例来说,这可能不是一个大问题,但它曾经给我带来过问题。
地图会变慢:
由于.get函数调用开销和缺乏内部优化,Map在某些任务中可能比普通的旧JavaScript对象慢得多。
根据MDN:
Map对象可以按插入顺序迭代其元素——for..of循环每次迭代将返回一个[key, value]数组。
and
Objects are similar to Maps in that both let you set keys to values,
retrieve those values, delete keys, and detect whether something is
stored at a key. Because of this, Objects have been used as Maps
historically; however, there are important differences between Objects
and Maps that make using a Map better.
An Object has a prototype, so there are default keys in the map.
However, this can be bypassed using map = Object.create(null). The
keys of an Object are Strings, where they can be any value for a Map.
You can get the size of a Map easily while you have to manually keep
track of size for an Object.
Map
按顺序迭代是开发人员一直想要的功能,部分原因是它可以确保在所有浏览器中都具有相同的性能。所以对我来说,这是一个大问题。
myMap.has(key)方法将特别方便,还有myMap.has(key)方法。大小属性。