在线文档教程

Map

Map

Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

语法

new Map([iterable])

参数

iterableIterable 可以是一个数组或者其他 iterable 对象,其元素或为键值对,或为两个元素的数组。 每个键值对都会添加到新的 Map。null会被当做 undefined。

描述

一个Map对象以插入顺序迭代其元素 — 一个  for...of 循环为每次迭代返回一个[key,value]数组。

应该注意的是,Map是一个对象的映射,将只映射到对象的插入顺序 - 这是随机的,而不是依照次序的。

键的相等(Key equality)

键的比较是基于 "SameValueZero" 算法:NaN是与 NaN相同的(虽然 NaN !== NaN),剩下所有其它的值是根据 === 运算符的结果判断是否相等。在目前的ECMAScript规范中,-0+0被认为是相等的,尽管这在早期的草案中并不是这样。有关详细信息,请参阅浏览器兼容性 表中的“value equality for -0 and 0”。

Objects 和 maps 的比较

Object和 Map类似的一点是,它们都允许你按键存取一个值,都可以删除键,还可以检测一个键是否绑定了值.因此,一直以来,我们都把对象当成Map来使用,不过,现在有了Map,下面的区别解释了为什么使用Map更好点.

  • 一个对象通常都有自己的原型,所以一个对象总有一个"prototype"键。不过,从 ES5 开始可以使用 map = Object.create(null)来创建一个没有原型的对象。

  • 一个对象的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。

  • 你可以通过size属性很容易地得到一个Map的键值对个数,而对象的键值对个数只能手动确认。

但是这并不意味着你可以随意使用 Map,对象仍旧是最常用的。如果你不确定要使用哪个,请思考下面的问题:

  • 在运行之前 key 是否是未知的,是否需要动态地查询 key 呢?

  • 是否所有的值都是统一类型,这些值可以互换么?

  • 是否需要不是字符串类型的 key ?

  • 键值对经常增加或者删除么?

  • 是否有任意个且非常容易改变的键值对?

  • 这个集合可以遍历么?

假如以上全是“是”的话,那么你需要用 Map 来保存这个集。 相反,你有固定数目的键值对,独立操作它们,区分它们的用法,那么你需要的是对象。

属性

Map.length属性 length 的值为 0 。get Map[@@species]本构造函数用于创建派生对象。Map.prototype表示 Map 构造器的原型。 允许添加属性从而应用于所有的 Map 对象。

Map示例

所有的 Map 对象实例都会继承Map.prototype

属性

Map.prototype.constructor返回一个函数,它创建了实例的原型。默认是Map函数。Map.prototype.size返回Map对象的键/值对的数量。

方法

Map.prototype.clear()移除Map对象的所有键/值对 。

示例

使用映射对象

var myMap = new Map( var 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' myMap.size; // 3 // getting the values myMap.get(keyString // "value associated with 'a string'" myMap.get(keyObj // "value associated with keyObj" myMap.get(keyFunc // "value associated with keyFunc" myMap.get('a string' // "value associated with 'a string'" // because keyString === 'a string' myMap.get{} // undefined, because keyObj !== {} myMap.get(function() {}) // undefined, because keyFunc !== function () {}

将NaN作为映射的键

NaN也可以作为Map对象的键. 虽然NaN和任何值甚至和自己都不相等(NaN !== NaN返回true), 但下面的例子表明,两个NaN作为Map的键来说是没有区别的:

var myMap = new Map( myMap.set(NaN, 'not a number' myMap.get(NaN // "not a number" var otherNaN = Number('foo' myMap.get(otherNaN // "not a number"

使用for..of方法迭代映射

映射也可以使用for..of循环来实现迭代:

var myMap = new Map( myMap.set(0, 'zero' myMap.set(1, 'one' for (var [key, value] of myMap) { console.log(key + ' = ' + value } // 0 = zero // 1 = one for (var key of myMap.keys()) { console.log(key } // 0 // 1 for (var value of myMap.values()) { console.log(value } // zero // one for (var [key, value] of myMap.entries()) { console.log(key + ' = ' + value } // 0 = zero // 1 = one

使用forEach()方法迭代映射

映射也可以通过forEach()方法迭代:

myMap.forEach(function(value, key) { console.log(key + ' = ' + value } // Will show 2 logs; first with "0 = zero" and second with "1 = one"

映射与数组对象的关系

var kvArray = [['key1', 'value1'], ['key2', 'value2']]; // Use the regular Map constructor to transform a 2D key-value Array into a map var myMap = new Map(kvArray myMap.get('key1' // returns "value1" // Use the Array.from function to transform a map into a 2D key-value Array console.log(Array.from(myMap) // Will show you exactly the same Array as kvArray // Or use the keys or values iterators and convert them to an array console.log(Array.from(myMap.keys()) // Will show ["key1", "key2"]

规范

SpecificationStatusComment
ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'Map' in that specification.StandardInitial definition.
ECMAScript Latest Draft (ECMA-262)The definition of 'Map' in that specification.Living Standard

浏览器兼容性

FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38 11213 (13)11257.1
Constructor argument: new Map(iterable)381213 (13)No support259
Map.clear()31 381219 (19)11257.1
Map.keys(), Map.values(), Map.entries()37 381220 (20)No support257.1
Map.forEach()36 381225 (25)11257.1
Key equality for -0 and 034 381229 (29)No support259
Constructor argument: new Map(null)(Yes)1237 (37)11(Yes)9
Map@@species511341 (41)No support3810
Map() without new throws(Yes)1242 (42)11(Yes)9

FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic supportNo support38 1(Yes)13.0 (13)No supportNo support8
Constructor argument: new Map(iterable)No support38(Yes)13.0 (13)No supportNo support9
Map.clear()No support31 38(Yes)19.0 (19)No supportNo support8
Map.keys(), Map.values(), Map.entries()No support37 38(Yes)20.0 (20)No supportNo support8
Map.forEach()No support36 38(Yes)25.0 (25)No supportNo support8
Key equality for -0 and 0No support34 38(Yes)29.0 (29)No supportNo supportNo support
Constructor argument: new Map(null)?(Yes)(Yes)37.0 (37)??9
Map@@species??(Yes)41.0 (41)??10
Map() without new throws5.1?(Yes)42.0 (42)??9