定义
键值对的集合,类似于对象,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果需要“键值对”的数据结构,Map 比 Object 更合适。
基本用法
创建map对象
任何具有Iterator 接口且每个成员都是一个双元素的数组的数据结构,都可以当做Map构造函数的参数
const set = new Set([
['set1', 1],
['set2', 2]
]);
const map1 = new Map(set);
console.log(map1) //Map(2) {'set1' => 1, 'set2' => 2}
const map2 = new Map([
["key1", 100],
["key2", 200],
["key3", 300]
]);
console.log(map2) //Map(3) {'key1' => 100, 'key2' => 200, 'key3' => 300}
对同一个键多次赋值,后面的值将覆盖前面的值
const map3 = new Map([
["key1", 100],
["key2", 200],
["key3", 300],
["key3", 400]
]);
console.log(map3) //Map(3) {'key1' => 100, 'key2' => 200, 'key3' => 400}
只有对同一个对象的引用,Map 结构才将其视为同一个键,Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键
const map4 = new Map();
map4 .set(['w'], 11);
console.log(map4 .get(['w'])) // undefined
如果Map 的键是一个简单类型的值(数字、字符串、布尔值)则只要两个值严格相等,Map 就将其视为一个键,比如0 和-0 就是一个键,布尔值true 和字符串true 则是两个不同的键,undefined和null 也是两个不同的键,虽然NaN不严格等于自身但是是一个键
let map5 = new Map();
map5.set(-0, 1);
console.log(map5.get(+0)) // 1
map5.set(true, 2);
map5.set('true', 3);
console.log(map5.get(true)) // 2
map5.set(undefined, 4);
map5.set(null, 5);
console.log(map5.get(undefined)) // 4
map5.set(NaN, 6);
console.log(map5.get(NaN)) // 6
将键值对放入map对象
map.set(key,value)
const map = new Map([
["key1", 100],
["key2", 200],
["key3", 300]
]);
map.set("key4",400)
console.log(map) //Map(4) {'key1' => 100, 'key2' => 200, 'key3' => 300, 'key4' => 400}
根据key获取map值
map.get(key)
const map = new Map([
["key1", 100],
["key2", 200],
["key3", 300]
]);
console.log(map.get("key3")) //300
删除map指定对象
delete map[key]
const set = new Set([
['set1', 1],
['set2', 2],
['set3', 3]
]);
const map = new Map(set);
map.delete("set2")
console.log(map) //Map(2) {'set1' => 1, 'set3' => 3}
遍历map - forEach方法
与数组的forEach 类似,都是用于遍历,还可以接受第二个参数用于绑定this 指向
const map = new Map()
.set('key1', 11)
.set(12, 345)
.set(null, 678)
map.forEach((value, key, map)=>{
console.log("Key: %s, Value: %s", key, value);
});
// Key: key1, Value: 11
// Key: 12, Value: 345
// Key: null, Value: 678
const reporter = {
report: function(key, value) {
console.log("mapKey: %s, mapValue: %s", key, value);
}
};
map.forEach(function(value, key, map) {
this.report(key, value);
}, reporter);
// mapKey: key1, mapValue: 11
// mapKey: 12, mapValue: 345
// mapKey: null, mapValue: 678
Map.prototype.keys()
:返回键名的遍历器
Map.prototype.values()
:返回键值的遍历器
Map.prototype.entries()
:返回所有成员的遍历器
需要特别注意的是,Map 的遍历顺序就是插入顺序
实例属性
size
const map = new Map([
["key1", 100],
["key2", 200],
["key3", 300]
]);
console.log(map.size) // 3
Map.prototype.set(key, value)
设置键名key 对应的键值为value,然后返回整个Map 结构,如果key 已经有值则键值会被覆盖,set 方法返回的是当前的Map 对象,因此可以采用链式写法
const map3 = new Map();
map3.set('key1', 1)
map3.set('key2', 2)
console.log(map3) //Map(2) {'key1' => 1, 'key2' => 2}
const map4 = new Map()
.set('key1', 11)
.set('key2', 22)
.set('key3', 33)
console.log(map4) //Map(3) {'key1' => 11, 'key2' => 22, 'key3' => 33}
Map.prototype.get(key)
读取key 对应的键值,没有则返回undefined
const map = new Map([
["key1", 100],
["key2", 200],
["key3", 300]
]);
console.log(map.get("key1")) // 100
console.log(map.get("key4")) // undefined
Map.prototype.has(key)
返回一个布尔值,表示某个键是否在当前 Map 对象之中
const map = new Map()
.set('key1', 11)
.set(12, 345)
.set(null, 678)
console.log(map.has('key1')) // true
console.log(map.has('key2')) // false
console.log(map.has(12)) // true
Map.prototype.delete(key)
delete()方法删除某个键,返回true,
如果删除失败返回false
const map = new Map()
.set('key1', 11)
.set(12, 345)
.set(null, 678)
console.log(map.delete('key1')) //true
console.log(map.delete('key2')) //false
Map.prototype.clear()
清除所有数据没有返回值
const map = new Map()
.set('key1', 11)
.set(12, 345)
.set(null, 678)
map.clear()
console.log(map) //Map(0) {size: 0}