我刚刚发现了这个特点:

Map: Map对象是简单的键/值映射。

这让我很困惑。常规JavaScript对象是字典,那么Map与字典有什么不同呢?从概念上讲,它们是相同的(根据Stack Overflow的另一个问题)

文档也没有帮助:

Map对象是键/值对的集合,其中键和值都可以是任意的ECMAScript语言值。不同的键值只能出现在Map集合中的一个键/值对中。使用创建Map时选择的比较算法进行区分的不同键值。

Map对象可以按插入顺序迭代其元素。Map对象必须使用哈希表或其他机制来实现,这些机制提供的访问时间平均与集合中元素的数量呈次线性关系。本Map对象规范中使用的数据结构仅用于描述Map对象所需的可观察语义。它并不是一个可行的实现模型。

听起来还是像个物件,显然我错过了什么。

为什么JavaScript获得一个(受良好支持的)Map对象?它能做什么?


当前回答

这两个技巧可以帮助你决定是使用Map还是Object:

当键在运行时之前未知时,以及当 所有键都是相同的类型,所有值都是相同的类型。 如果需要将原始值存储为键,则使用映射 因为object将每个键都视为字符串,要么是数字值, 布尔值或任何其他基本值。 当存在操作单个元素的逻辑时使用对象。

来源:键集合

其他回答

根据Mozilla

JavaScript中对象与地图的简短示例。

Object-遵循与map相同的概念,即使用键值对存储数据。但也有细微的差异,使得地图在某些情况下表现更好。

Map-是一种数据结构,有助于以对的形式存储数据。这一对由一个唯一键和映射到该键的值组成。这有助于防止口是心非。

关键的不同点

Map是对象的实例,反之则不然。

var map = new map (); var obj = new Object(); console.log(obj instanceof Map);/ /错误 console.log(映射实例对象);/ /正确的

在Object中,键字段的数据类型被限制为整数、字符串和符号。而在Map中,键字段可以是任何数据类型(整数、数组、对象)

var map = new map();//空 map.set (1, ' 1 '); 地图。(' 1 ', 1); 地图。set('{}', {name:'Hello, World!'}); map.set (12.3, 12.3) map.set([12]、[12345]) (let [key,value] of map.entries()) console.log(键+“-”+值)

在Map中,元素的原始顺序被保留。这在对象的情况下是不正确的。

让obj ={ 1: ' 1 ', “一”:1、 '{}': {name:'Hello world'}, 12.3:12.3, [12]: [100] } console.log (obj)

除了上面提到的可用性差异,如果你对大型对象的性能差异更感兴趣,普通对象在chrome上设置、更新和删除大量数据时似乎要快2倍。

Experiment here: https://perf.link/#eyJpZCI6ImNncmtpcGdlMzhsIiwidGl0bGUiOiJGaW5kaW5nIG51bWJlcnMgaW4gYW4gYXJyYXkgb2YgMTAwMCIsImJlZm9yZSI6ImNvbnN0IGRhdGEgPSBbLi4uQXJyYXkoMTAwMDAwKS5rZXlzKCldXG4iLCJ0ZXN0cyI6W3sibmFtZSI6IkZpbmQgaXRlbSAxMDAiLCJjb2RlIjoiY29uc3Qgb2JqID0ge31cbmZvciAoY29uc3QgdiBvZiBkYXRhKSB7XG4gICBvYmpbdl0gPSB2XG59XG5cbmZvciAoY29uc3QgdiBvZiBkYXRhKSB7XG4gICBvYmpbdl0gPSB2ICsgMVxufVxuXG5mb3IgKGNvbnN0IHYgb2YgZGF0YSkge1xuICAgZGVsZXRlIG9ialt2XVxufSIsInJ1bnMiOlsxMTUsMTE1LDExNSwxMTUsMTE1LDExNSwxMDksMTE1LDEwOSwxMTUsMTE1LDExNSwxMDksMTE1LDExNSwxMTUsMTA5LDEwOSwxMDksMTE1LDEwOSwxMDksMTE1LDEwOSwxMTUsMTA5LDEwOSwxMTUsMTA5LDExNSwxMDksMTE1LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDExNSwxMDksMTA5LDEwOSwxMDksMTE1LDEwOSwxMDksMTA5LDEwOSwxMDksMTE1LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMTUsMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMTUsMTE1LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDksMTA5LDEwOSwxMDldLCJvcHMiOjExMH0seyJuYW1lIjoiRmluZCBpdGVtIDIwMCIsImNvZGUiOiJjb25zdCBvYmogPSBuZXcgTWFwKClcbmZvciAoY29uc3QgdiBvZiBkYXRhKSB7XG4gICBvYmouc2V0KHYsIHYpXG59XG5cbmZvciAoY29uc3QgdiBvZiBkYXRhKSB7XG4gICBvYmouc2V0KHYsIHYgKyAxKVxufVxuXG5mb3IgKGNvbnN0IHYgb2YgZGF0YSkge1xuICAgb2JqLmRlbGV0ZSh2KVxufSIsInJ1bnMiOls2Myw1Nyw1Nyw2Myw1Nyw2Myw1Nyw1Nyw1Nyw2Myw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw2Myw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1Nyw1N10sIm9wcyI6NTd9XSwidXBkYXRlZCI6IjIwMjItMDYtMTVUMTg6MTQ6MjYuNjA2WiJ9

对象的行为类似于字典,因为JavaScript是动态类型的,允许您随时添加或删除属性。

但是Map()更好,因为它:

提供get、set、has和delete方法。 接受任何类型的键,而不仅仅是字符串。 提供一个易于for-of使用的迭代器,并维护结果的顺序。 在迭代或复制过程中不会出现原型和其他属性的边缘情况。 支持数百万项。 非常快。

如果需要字典,则使用Map()。

但是,如果您只使用基于字符串的键,并且需要最大的读取性能,那么对象可能是更好的选择。这是因为JavaScript引擎在后台将对象编译为c++类,并且属性的访问路径比Map().get()的函数调用要快得多。

这些类也被缓存,所以创建一个具有完全相同属性的新对象意味着引擎将重用一个现有的后台类。添加或删除属性会导致类的形状改变,并重新编译支持类,这就是为什么将一个对象用作添加和删除大量内容的字典会非常慢,但是在不更改对象的情况下读取现有键会非常快。

因此,如果您有一个写一次读的繁重的工作负载和字符串键,那么您可以使用对象作为高性能的字典,但对于其他所有事情使用Map()。

根据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)方法。大小属性。

这是我记住它的一个简单方法:KOI

Keys. Object key is strings or symbols. Map keys can also be numbers (1 and "1" are different), objects, NaN, etc. It uses === to distinguish between keys, with one exception NaN !== NaN but you can use NaN as a key. Order. The insertion order is remembered. So [...map] or [...map.keys()] has a particular order. Interface. Object: obj[key] or obj.a (in some language, [] and []= are really part of the interface). Map has get(), set(), has(), delete() etc. Note that you can use map[123], but that is using it as a plain JavaScript object.