基本API

  • 使用 new 关键字和 Map 构造函数可以创建一个空映射;
  • 如果想在创建的同时初始化实例,可以给 Map 构造函数传入一个可迭代对象,需要包含键/值对数组:
  • 初始化之后,可以使用 set()方法再添加键/值对;
  • 可以使用 get()和 has()进行查询;
  • 可以通过 size 属性获取映射中的键/值对的数量;
  • 可以使用 delete()和 clear()删除值;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 使用嵌套数组初始化映射
const m1 = new Map([
["key1", "val1"],
["key2", "val2"],
["key3", "val3"]
]);
alert(m1.size); // 3

const m = new Map();
alert(m.has("firstName")); // false
alert(m.get("firstName")); // undefined
alert(m.size); // 0
m.set("firstName", "Matt")
.set("lastName", "Frisbie");
alert(m.has("firstName")); // true
alert(m.get("firstName")); // Matt
alert(m.size); // 2
m.delete("firstName"); // 只删除这一个键/值对
alert(m.has("firstName")); // false
alert(m.has("lastName")); // true
alert(m.size); // 1
m.clear(); // 清除这个映射实例中的所有键/值对
alert(m.has("firstName")); // false
alert(m.has("lastName")); // false
alert(m.size); // 0
  • Map 可以使用任何 JavaScript 数据类型作为键;
1
2
3
4
5
6
7
8
9
10
11
12
const m = new Map(); 
const functionKey = function() {};
const symbolKey = Symbol();
const objectKey = new Object();
m.set(functionKey, "functionValue");
m.set(symbolKey, "symbolValue");
m.set(objectKey, "objectValue");
alert(m.get(functionKey)); // functionValue
alert(m.get(symbolKey)); // symbolValue
alert(m.get(objectKey)); // objectValue
// SameValueZero 比较意味着独立实例不冲突
alert(m.get(function() {})); // undefined
  • 在映射中用作键和值的对象及其他“集合”类型,在自己的内容或属性被修改时依然保持不变;
1
2
3
4
5
6
7
8
9
10
11
12
13
const m = new Map(); 
const objKey = {},
objVal = {},
arrKey = [],
arrVal = [];
m.set(objKey, objVal);
m.set(arrKey, arrVal);
objKey.foo = "foo";
objVal.bar = "bar";
arrKey.push("foo");
arrVal.push("bar");
console.log(m.get(objKey)); // {bar: "bar"}
console.log(m.get(arrKey)); // ["bar"]

顺序与迭代

  • Map 实例会维护键值对的插入顺序;
  • 映射实例可以提供一个迭代器(Iterator),能以插入顺序生成[key, value]形式的数组。可以通过**entries()**方法(或者 Symbol.iterator 属性,它引用 entries())取得这个迭代器;
1
2
3
4
5
6
const m = new Map([ 
["key1", "val1"],
["key2", "val2"],
["key3", "val3"]
]);
alert(m.entries === m[Symbol.iterator]); // true
  • entries()是默认迭代器,可以直接对映射实例使用扩展操作,把映射转换为数组;
1
2
3
4
5
6
const m = new Map([ 
["key1", "val1"],
["key2", "val2"],
["key3", "val3"]
]);
console.log([...m]); // [[key1,val1],[key2,val2],[key3,val3]]
  • forEach(callback,opt_thisArg)方法同样可以迭代每个键/值对,第一个参数传入一个回调方法
  • 第二个参数用于重写回调函数内部的this值;
1
2
3
4
5
6
7
8
9
const m = new Map([ 
["key1", "val1"],
["key2", "val2"],
["key3", "val3"]
]);
m.forEach((val, key) => alert(`${key} -> ${val}`));
// key1 -> val1
// key2 -> val2
// key3 -> val3
  • keys()和 values()分别返回以插入顺序生成键和值的迭代器;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const m = new Map([ 
["key1", "val1"],
["key2", "val2"],
["key3", "val3"]
]);
for (let key of m.keys()) {
alert(key);
}
// key1
// key2
// key3
for (let key of m.values()) {
alert(key);
}
// value1
// value2
// value3
  • 键和值在迭代器遍历时是可以修改的,但映射内部的引用则无法修改;
  • 修改了作为键的对象的属性,但对象在映射内部仍然引用相同的值;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const m1 = new Map([ 
["key1", "val1"]
]);

for (let key of m1.keys()) {
key = "newKey";
alert(key); // newKey
alert(m1.get("key1")); // val1
}

const keyObj = {id: 1};
const m = new Map([
[keyObj, "val1"]
]);