我刚刚发现了这个特点:
Map: Map对象是简单的键/值映射。
这让我很困惑。常规JavaScript对象是字典,那么Map与字典有什么不同呢?从概念上讲,它们是相同的(根据Stack Overflow的另一个问题)
文档也没有帮助:
Map对象是键/值对的集合,其中键和值都可以是任意的ECMAScript语言值。不同的键值只能出现在Map集合中的一个键/值对中。使用创建Map时选择的比较算法进行区分的不同键值。
Map对象可以按插入顺序迭代其元素。Map对象必须使用哈希表或其他机制来实现,这些机制提供的访问时间平均与集合中元素的数量呈次线性关系。本Map对象规范中使用的数据结构仅用于描述Map对象所需的可观察语义。它并不是一个可行的实现模型。
听起来还是像个物件,显然我错过了什么。
为什么JavaScript获得一个(受良好支持的)Map对象?它能做什么?
我认为到目前为止答案中还没有提到以下几点,我认为它们值得一提。
地图可以更大
在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对象慢得多。
这是我记住它的一个简单方法: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.
简介:
Object: A data structure in which data is stored as key value pairs. In an object the key has to be a number, string, or symbol. The value can be anything so also other objects, functions, etc. An object is a nonordered data structure, i.e. the sequence of insertion of key value pairs is not remembered
ES6 Map: A data structure in which data is stored as key value pairs. In which a unique key maps to a value. Both the key and the value can be in any data type. A map is an iterable data structure. This means that the sequence of insertion is remembered and that we can access the elements in e.g. a for..of loop.
关键的不同点:
Map是有序的且可迭代的,而object不是有序的且不可迭代的(也就是说它们没有[符号]。迭代器]属性。但是,你可以在语法中使用for..遍历键。)
我们可以将任何类型的数据作为Map键,而对象只能将数字、字符串或符号作为键。
Map继承自Map.prototype。这提供了各种实用函数和属性,使Map对象的工作更加容易。
例子:
对象:
让obj = {};
//添加属性到对象
obj。Prop1 = 1;
Obj [2] = 2;
//获取对象属性的nr
console.log(种(obj) . length)
//删除属性
删除obj [2]
console.log (obj)
Map:
const myMap = new Map();
const keyString = 'a string',
keyObj = {},
keyFunc = function() {};
// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, 'value associated with keyObj');
myMap.set(keyFunc, 'value associated with keyFunc');
console.log(myMap.size); // 3
// getting the values
console.log(myMap.get(keyString)); // "value associated with 'a string'"
console.log(myMap.get(keyObj)); // "value associated with keyObj"
console.log(myMap.get(keyFunc)); // "value associated with keyFunc"
console.log(myMap.get('a string')); // "value associated with 'a string'"
// because keyString === 'a string'
console.log(myMap.get({})); // undefined, because keyObj !== {}
console.log(myMap.get(function() {})) // undefined, because keyFunc !== function () {}
来源:中数
除了按定义良好的顺序可迭代,以及能够使用任意值作为键(除了-0)之外,map还很有用,原因如下:
The spec enforces map operations to be sublinear on average.
Any non-stupid implementation of object will use a hash table or similar, so property lookups will probably be constant on average. Then objects could be even faster than maps. But that is not required by the spec.
Objects can have nasty unexpected behaviors.
For example, let's say you didn't set any foo property to a newly created object obj, so you expect obj.foo to return undefined. But foo could be built-in property inherited from Object.prototype. Or you attempt to create obj.foo by using an assignment, but some setter in Object.prototype runs instead of storing your value.
Maps prevent these kind of things. Well, unless some script messes up with Map.prototype. And Object.create(null) would work too, but then you lose the simple object initializer syntax.