Map

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

语法

new Map([iterable])

参数

iterable
Iterable 可以是一个 数组或者其他 iterable 对象,其元素为键值对(两个元素的数组,例如: [[ 1, 'one' ],[ 2, 'two' ]])。 每个键值对都会添加到新的 Map。 null 会被当做  undefined。

描述

一个Map对象在迭代时会根据对象中元素的插入顺序来进行 — 一个  for...of 循环在每次迭代后会返回一个形式为[key,value]的数组。

键的相等(Key equality)

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

Objects 和 maps 的比较

Objects 和 Maps 类似的是,它们都允许你按键存取一个值、删除键、检测一个键是否绑定了值。因此(并且也没有其他内建的替代方式了)过去我们一直都把对象当成 Maps 使用。不过 Maps 和 Objects 有一些重要的区别,在下列情况里使用 Map 会是更好的选择:

  • 一个Object的键只能是Symbols,但一个 Map 的键可以是任意值,包括函数、对象、基本类型。
  • Map 中的键值是有序的,而添加到对象中的键则不是。因此,当对它进行遍历时,Map 对象是按插入的顺序返回键值。
  • 你可以通过 size 属性直接获取一个 Map 的键值对个数,而 Object 的键值对个数只能手动计算。
  • Map 可直接进行迭代,而 Object 的迭代需要先获取它的键数组,然后再进行迭代。
  • Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。虽然 ES5 开始可以用 map = Object.create(null) 来创建一个没有原型的对象,但是这种用法不太常见。
  • 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对象的所有键/值对 。
Map.prototype.delete(key)
如果  Map 对象中存在该元素,则移除它并返回  true;否则如果该元素不存在则返回  false
Map.prototype.entries()
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
Map.prototype.forEach(callbackFn[, thisArg])
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,它将在每次回调中作为this值。
Map.prototype.get(key)
返回键对应的值,如果不存在,则返回undefined。
Map.prototype.has(key)
返回一个布尔值,表示Map实例是否包含键对应的值。
Map.prototype.keys()
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的
Map.prototype.set(key, value)
设置Map对象中键的值。返回该Map对象。
Map.prototype.values()
返回一个新的 Iterator对象,它按插入顺序包含了Map对象中每个元素的
Map.prototype[@@iterator]()
返回一个新的 Iterator对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组

示例

使用 Map 对象

var myMap = new Map();
 
var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";
 
// 添加键
myMap.set(keyString, "和键'a string'关联的值");
myMap.set(keyObj, "和键keyObj关联的值");
myMap.set(keyFunc, "和键keyFunc关联的值");
 
myMap.size; // 3
 
// 读取值
myMap.get(keyString);    // "和键'a string'关联的值"
myMap.get(keyObj);       // "和键keyObj关联的值"
myMap.get(keyFunc);      // "和键keyFunc关联的值"
 
myMap.get("a string");   // "和键'a string'关联的值"
                         // 因为keyString === 'a string'
myMap.get({});           // undefined, 因为keyObj !== {}
myMap.get(function() {}) // undefined, 因为keyFunc !== function () {}

将 NaN 作为 Map 的键

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 方法迭代 Map

Map可以使用for..of循环来实现迭代:

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// 将会显示两个log。一个是"0 = zero"另一个是"1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// 将会显示两个log。 一个是 "0" 另一个是 "1"

for (var value of myMap.values()) {
  console.log(value);
}
// 将会显示两个log。 一个是 "zero" 另一个是 "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// 将会显示两个log。 一个是 "0 = zero" 另一个是 "1 = one"

使用 forEach() 方法迭代 Map

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

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
})
// 将会显示两个logs。 一个是 "0 = zero" 另一个是 "1 = one"

Map 与数组的关系

var kvArray = [["key1", "value1"], ["key2", "value2"]];

// 使用常规的Map构造函数可以将一个二维键值对数组转换成一个Map对象
var myMap = new Map(kvArray);

myMap.get("key1"); // 返回值为 "value1"

// 使用Array.from函数可以将一个Map对象转换成一个二维键值对数组
console.log(Array.from(myMap)); // 输出和kvArray相同的数组

// 或者在键或者值的迭代器上使用Array.from,进而得到只含有键或者值的数组
console.log(Array.from(myMap.keys())); // 输出 ["key1", "key2"]

复制或合并 Maps

Map 能像数组一样被复制:

var original = new Map([
  [1, 'one']
]);

var clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false. Useful for shallow comparison

请记住,数据本身未被克隆。

Map对象间可以进行合并,但是会保持键的唯一性。

var first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

var second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);

// 合并两个Map对象时,如果有重复的键值,则后面的会覆盖前面的。
// 展开运算符本质上是将Map对象转换成数组。
var merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

Map对象也能与数组合并:

var first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

var second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);

// Map对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。
var merged = new Map([...first, ...second, [1, 'eins']]);

console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

规范

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
Map
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
Map
Draft

浏览器兼容

Update compatibility data on GitHub
Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
Map Chrome Full support 38 Edge Full support 12 Firefox Full support 13 IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 14 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
Full support 0.12
Full support 0.10
Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
clear Chrome Full support 38 Edge Full support 12 Firefox Full support 19 IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 19 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
delete Chrome Full support 38 Edge Full support 12 Firefox Full support 13 IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 14 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
Full support 0.12
Full support 0.10
Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
entries Chrome Full support 38 Edge Full support 12 Firefox Full support 20 IE No support No Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 20 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
forEach Chrome Full support 38 Edge Full support 12 Firefox Full support 25 IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 25 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
get Chrome Full support 38 Edge Full support 12 Firefox Full support 13 IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 14 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support Yes
has Chrome Full support 38 Edge Full support 12 Firefox Full support 13 IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 14 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support Yes
Key equality for -0 and 0 Chrome Full support 38 Edge Full support 12 Firefox Full support 29 IE No support No Opera Full support 25 Safari Full support 9 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 29 Opera Android Full support 25 Safari iOS Full support 9 Samsung Internet Android Full support 3.0 nodejs Full support 4.0.0
keys Chrome Full support 38 Edge Full support 12 Firefox Full support 20 IE No support No Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 20 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
new Map(iterable) Chrome Full support 38 Edge Full support 12 Firefox Full support 13 IE No support No Opera Full support 25 Safari Full support 9 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 14 Opera Android Full support 25 Safari iOS Full support 9 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
new Map(null) Chrome Full support 38 Edge Full support 12 Firefox Full support 37 IE Full support 11 Opera Full support 25 Safari Full support 9 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 37 Opera Android Full support 25 Safari iOS Full support 9 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
Full support 0.12
Full support 0.10
Disabled
Disabled From version 0.10: this feature is behind the --harmony runtime flag.
Map() without new throws Chrome Full support 38 Edge Full support 12 Firefox Full support 42 IE Full support 11 Opera Full support 25 Safari Full support 9 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 42 Opera Android Full support 25 Safari iOS Full support 9 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
prototype Chrome Full support 38 Edge Full support 12 Firefox Full support 13 IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 14 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support Yes
set Chrome Full support 38 Edge Full support 12 Firefox Full support 13 IE Partial support 11
Notes
Partial support 11
Notes
Notes Returns 'undefined' instead of the 'Map' object.
Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 14 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support Yes
size Chrome Full support 38 Edge Full support 12 Firefox Full support 19
Notes
Full support 19
Notes
Notes From Firefox 13 to Firefox 18, the size property was implemented as a Map.prototype.size() method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification.
IE Full support 11 Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 19
Notes
Full support 19
Notes
Notes From Firefox 13 to Firefox 18, the size property was implemented as a Map.prototype.size() method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification.
Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
values Chrome Full support 38 Edge Full support 12 Firefox Full support 20 IE No support No Opera Full support 25 Safari Full support 8 WebView Android Full support 38 Chrome Android Full support 38 Firefox Android Full support 20 Opera Android Full support 25 Safari iOS Full support 8 Samsung Internet Android Full support 3.0 nodejs Full support 0.12
@@iterator Chrome Full support 43 Edge Full support 12 Firefox Full support 36
Full support 36
No support 27 — 36
Notes Alternate Name
Notes A placeholder property named @@iterator is used.
Alternate Name Uses the non-standard name: @@iterator
No support 17 — 27
Notes Alternate Name
Notes A placeholder property named iterator is used.
Alternate Name Uses the non-standard name: iterator
IE No support No Opera Full support 30 Safari Full support Yes WebView Android Full support 43 Chrome Android Full support 43 Firefox Android Full support 36
Full support 36
No support 27 — 36
Notes Alternate Name
Notes A placeholder property named @@iterator is used.
Alternate Name Uses the non-standard name: @@iterator
No support 17 — 27
Notes Alternate Name
Notes A placeholder property named iterator is used.
Alternate Name Uses the non-standard name: iterator
Opera Android Full support 30 Safari iOS Full support Yes Samsung Internet Android Full support 4.0 nodejs Full support 0.12
@@species Chrome Full support 51 Edge Full support 13 Firefox Full support 41 IE No support No Opera Full support 38 Safari Full support 10 WebView Android Full support 51 Chrome Android Full support 51 Firefox Android Full support 41 Opera Android Full support 41 Safari iOS Full support 10 Samsung Internet Android Full support 5.0 nodejs Full support 6.5.0
Full support 6.5.0
Full support 6.0.0
Disabled
Disabled From version 6.0.0: this feature is behind the --harmony runtime flag.
@@toStringTag Chrome Full support 44 Edge No support No Firefox Full support 51 IE No support No Opera No support No Safari No support No WebView Android Full support 44 Chrome Android Full support 44 Firefox Android Full support 51 Opera Android No support No Safari iOS No support No Samsung Internet Android Full support 4.0 nodejs No support No

Legend

Full support  
Full support
Partial support  
Partial support
No support  
No support
See implementation notes.
See implementation notes.
User must explicitly enable this feature.
User must explicitly enable this feature.
Uses a non-standard name.
Uses a non-standard name.

相关链接