# Map
# Map
Map 是一组键值对的结构,用于解决以往不能用对象做为键的问题
- 具有极快的查找速度
- 函数、对象、基本类型都可以作为键或值
# 声明定义
可以接受一个数组作为参数,该数组的成员是一个表示键值对的数组。
// 方式一
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
console.log(m); // Map(2) {'aaa' => '语文', 'bbb' => '数学'}
// 方式二
let map = new Map();
let obj = {
name: "木子李",
};
map.set(obj, "哈哈哈");
console.log(map.get(obj)); // 哈哈哈
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 获取元素(get
)
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
console.log(m.get("aaa")); // 语文
1
2
3
4
5
6
2
3
4
5
6
# 添加修改元素(set
)
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
// set方法添加或修改元素,支持链式操作
m.set("ccc", "英语").set("ddd", "物理");
console.log(m); // Map(4) {'aaa' => '语文', 'bbb' => '数学', 'ccc' => '英语', 'ddd' => '物理'}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 删除元素(delete、clear
)
删除单个
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
m.delete("aaa");
console.log(m); // Map(1) {'bbb' => '数学'}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
全部删除
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
m.clear("aaa");
console.log(m); // Map(0) {size: 0}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 获取数量(size
)
获取数据的数量
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
console.log(m.size); // 2
1
2
3
4
5
6
2
3
4
5
6
# 检测元素(has
)
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
console.log(m.has("aaa")); // true
1
2
3
4
5
6
2
3
4
5
6
# 遍历数据
使用 keys()/values()/entries()
都可以返回可遍历的迭代对象。
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
console.log(m.keys()); // MapIterator {'aaa', 'bbb'}
console.log(m.values()); // MapIterator {'语文', '数学'}
console.log(m.entries()); // MapIterator {'aaa' => '语文', 'bbb' => '数学'}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
可以使用keys/values
函数遍历键与值
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
for (const key of m.keys()) {
console.log(key); // aaa bbb
}
for (const value of m.values()) {
console.log(value); // 语文 数学
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
使用for/of
遍历操作,直接遍历Map
等同于使用entries()
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
for (const [key, value] of m) {
console.log(`[${key},${value}]`); // [aaa,语文] [bbb,数学]
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
使用forEach
遍历操作
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
m.forEach((value, key) => {
console.log(`[${key},${value}]`); // [aaa,语文] [bbb,数学]
});
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 类型转换
可以使用 展开语法
或 Array.form
静态方法将 Set 类型转为数组,这样就可以使用数组处理函数了
let m = new Map([
["aaa", "语文"],
["bbb", "数学"],
]);
console.log(...m); // ['aaa', '语文'] ['bbb', '数学']
console.log(...m.keys()); // aaa bbb
console.log(...m.values()); // 语文 数学
console.log(...m.entries()); // ['aaa', '语文'] ['bbb', '数学']
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# WeakMap
WeakMap 对象是一组键/值对的集
- 键名必须是对象
WeaMap
对键名是弱引用的,键值是正常引用- 垃圾回收不考虑
WeaMap的
键名,不会改变引用计数器,键在其他地方不被引用时即删除 - 因为
WeakMap
是弱引用,由于其他地方操作成员可能会不存在,所以不可以进行forEach( )
遍历等操作 - 也是因为弱引用,
WeaMap
结构没有keys( ),values( ),entries( )
等方法和size
属性 - 当键的外部引用删除时,希望自动删除数据时使用
WeakMap
# 声明定义
以下操作由于键不是对象类型将产生错误
new WeakSet("木子李"); //TypeError: Invalid value used in weak set
1
# 基本操作
const wm = new WeakMap();
const arr = ["木子李"];
//添加操作
wm.set(arr, "语文");
console.log(wm); // WeakMap {Array(1) => '语文'}
console.log(wm.has(arr)); //true
//删除操作
wm.delete(arr);
//检索判断
console.log(wm.has(arr)); //false
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 垃圾回收
WakeMap
的键名对象不会增加引用计数器,如果一个对象不被引用了会自动删除。
- 下例当
wm
删除时内存即清除,因为WeakMap
是弱引用不会产生引用计数 - 当垃圾回收时因为对象被删除,这时
WakeMap
也就没有记录了
let map = new WeakMap();
let wm = {
'aa': '语文'
};
map.set(wm, "木子李");
console.log('1',map);
wm = null;
console.log('2',map);
setTimeout(() => {
console.log('3',map);
}, 1000);
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13