非常教程

JavaScript参考手册

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对象的所有键/值对 。

Map.prototype.delete(key)移除任何与键相关联的值,并且返回该值,该值在之前会被Map.prototype.has(key)返回为true。之后再调用Map.prototype.has(key)会返回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]数组

示例

使用映射对象

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"]

规范

Specification

Status

Comment

ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'Map' in that specification.

Standard

Initial definition.

ECMAScript Latest Draft (ECMA-262)The definition of 'Map' in that specification.

Living Standard

浏览器兼容性

Feature

Chrome

Edge

Firefox (Gecko)

Internet Explorer

Opera

Safari

Basic support

38 1

12

13 (13)

11

25

7.1

Constructor argument: new Map(iterable)

38

12

13 (13)

No support

25

9

Map.clear()

31 38

12

19 (19)

11

25

7.1

Map.keys(), Map.values(), Map.entries()

37 38

12

20 (20)

No support

25

7.1

Map.forEach()

36 38

12

25 (25)

11

25

7.1

Key equality for -0 and 0

34 38

12

29 (29)

No support

25

9

Constructor argument: new Map(null)

(Yes)

12

37 (37)

11

(Yes)

9

Map@@species

51

13

41 (41)

No support

38

10

Map() without new throws

(Yes)

12

42 (42)

11

(Yes)

9

Feature

Android

Chrome for Android

Edge

Firefox Mobile (Gecko)

IE Mobile

Opera Mobile

Safari Mobile

Basic support

No support

38 1

(Yes)

13.0 (13)

No support

No support

8

Constructor argument: new Map(iterable)

No support

38

(Yes)

13.0 (13)

No support

No support

9

Map.clear()

No support

31 38

(Yes)

19.0 (19)

No support

No support

8

Map.keys(), Map.values(), Map.entries()

No support

37 38

(Yes)

20.0 (20)

No support

No support

8

Map.forEach()

No support

36 38

(Yes)

25.0 (25)

No support

No support

8

Key equality for -0 and 0

No support

34 38

(Yes)

29.0 (29)

No support

No support

No support

Constructor argument: new Map(null)

?

(Yes)

(Yes)

37.0 (37)

?

?

9

Map@@species

?

?

(Yes)

41.0 (41)

?

?

10

Map() without new throws

5.1

?

(Yes)

42.0 (42)

?

?

9

Map
Map 详细
map.@@iterator 详细
Map.@@species 详细
map.@@toStringTag 详细
map.clear 详细
map.delete 详细
map.entries 详细
map.forEach 详细
map.get 详细
map.has 详细
map.keys 详细
Map.prototype 详细
map.set 详细
map.size 详细
map.values 详细
JavaScript

JavaScript 是一种高级编程语言,通过解释执行,是一门动态类型,面向对象(基于原型)的解释型语言。它已经由ECMA(欧洲电脑制造商协会)通过 ECMAScript 实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器( Chrome、IE、FireFox、Safari、Opera )支持。JavaScript 是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络