一、Map()
1.1 简介
ES6 提供了 Map 数据结构,它类似于对象,是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
我们可以通过 new Map()去创建它。
1.2. Map的创建、设置与获取
1.对单个数据设置与获取
<script>
//创建Map对象
const mapData = new Map();
//添加数据(键,值)
mapData.set("name", "张三");
//获取数据
console.log(mapData.get("name")); //张三
</script>
1.3 对多个数据的设置与获取
<script>
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const infos = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
//创建Map对象
const mapData = new Map();
//将数据存入Map对象
arr.forEach((item, index) => {
mapData.set(item, infos[index]);
});
//遍历Map对象
arr.forEach((item, index) => {
console.log(mapData.get(item)); //a b c d e f g h i j
});
//下面的方法后文有介绍
console.log(mapData.size); //10
console.log(mapData.has(1)); //true
console.log(mapData.has(11)); //false
console.log(mapData.get(1)); //a
</script>
1.3 注意事项
1.对同一个键多次赋值,后面的值将覆盖前面的值
2.如果读取一个未知的键,则返回undefined。同一内存地址才是同一个键,不同内存地址但是值 相同不算同一个键。例如:
const map = new Map();
map.set(["a"], 555);
console.log(map.get(["a"])); // undefined
</script>
1.3 Map()的一些方法
1.size 返回 Map 结构的成员总数。
2.has 方法返回一个布尔值,表示某个键是否在当前 Map 对象之中
3.delete 删除一个键,成功返回true,失败返回false
4.clear 清除所有成员
示例:
<script>
// 创建一个 Map 对象
const myMap = new Map();
// 添加一些键值对
myMap.set("key1", "value1");
myMap.set("key2", "value2");
myMap.set("key3", "value3");
// 示例1:size 方法
console.log("Map size:", myMap.size); // 输出:3
// 示例2:has 方法
console.log(myMap.has("key1")); // 输出:true
console.log(myMap.has("nonExistentKey")); // 输出:false
// 示例3:delete 方法
console.log(myMap.delete("key2")); // 输出:true (删除成功)
console.log(myMap.has("key2")); // 输出:false ('key2' 已经被删除)
// 示例4:clear 方法
myMap.clear();
console.log("清空:", myMap.size); // 输出:0 (所有成员已被清除)
</script>
1.4 遍历Map
Map.prototype.keys():返回键名的遍历器。
Map.prototype.values():返回键值的遍历器。
Map.prototype.entries():返回所有成员的遍历器。
Map.prototype.forEach():遍历 Map 的所有成员。
示例:
<script>
// 创建一个 Map 对象
const myMap = new Map();
myMap.set("name", "Alice");
myMap.set("age", 25);
myMap.set("city", "New York");
// 示例1:Map.prototype.keys()
for (const key of myMap.keys()) {
console.log("Key:", key);
}
// 输出:
// Key: name
// Key: age
// Key: city
// 示例2:Map.prototype.values()
for (const value of myMap.values()) {
console.log("Value:", value);
}
// 输出:
// Value: Alice
// Value: 25
// Value: New York
// 示例3:Map.prototype.entries()
for (const [key, value] of myMap.entries()) {
console.log(`Key: ${key}, Value: ${value}`);
}
// 输出:
// Key: name, Value: Alice
// Key: age, Value: 25
// Key: city, Value: New York
// 示例4:Map.prototype.forEach()
myMap.forEach((value, key) => {
console.log(`Key: ${key}, Value: ${value}`);
});
// 输出:
// Key: name, Value: Alice
// Key: age, Value: 25
// Key: city, Value: New York
</script>
1.5 Map与其它数据类型互换
1.Map与数组
Map=>数组
<script>
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const infos = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
const mapData = new Map();
arr.forEach((item, index) => {
mapData.set(item, infos[index]);
});
//两种方式都可以将map转换为数组
console.log(Array.from(mapData)); //[[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "f"], [7, "g"], [8, "h"], [9, "i"], [10, "j"]
console.log([...mapData]); //[[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "f"], [7, "g"], [8, "h"], [9, "i"], [10, "j"]
</script>
数组=>Map
<script>
const arr = [
[1, "a"],
[2, "b"],
[3, "c"],
[4, "d"],
[5, "e"],
[6, "f"],
[7, "g"],
[8, "h"],
[9, "i"],
[10, "j"],
];
console.log(new Map(arr)); //Map(10) { 1 => 'a', 2 => 'b', 3 => 'c', 4 => 'd', 5 => 'e', 6 => 'f', 7 => 'g', 8 => 'h', 9 => 'i', 10 => 'j' }
</script>
2.Map与对象
Map=>对象
<script>
const mapData = new Map([
["name", "老王"],
["age", 30],
["city", "王家屯"],
]);
// 将Map转换为对象
console.log(Object.fromEntries(mapData)); // { name: '老王', age: 30, city: '王家屯' }
</script>
对象=>Map
<script>
const obj = {
name: "老张",
age: 29,
city: "张家集",
};
console.log(new Map(Object.entries(obj))); //Map(3) {"name" => "老张", "age" => 29, "city" => "张家集"}
</script>
3.Map与JSON
Map=>JSON
<script>
const map = new Map(
Object.entries({
name: "老张",
age: 29,
city: "张家集",
})
);
console.log(JSON.stringify([...map]));//[["name","老张"],["age",29],["city","张家集"]]
</script>
JSON=>Map
<script>
const map = new WeakMap();
// 创建一个对象作为键
const key = { name: "老王" };
map.set(key, "这是老王的数据");
console.log(map.get(key)); // 这是老王的数据
</script>
<script>
const jsonData = [
["name", "老张"],
["age", 29],
["city", "张家集"],
];
console.log(
new Map(Object.entries(JSON.parse(JSON.stringify(jsonData))))
);// Map(3) {"name" => "老张", "age" => 29, "city" => "张家集"}
</script>
二、WeakMap
2.1 简介
WeakMap和Map一样是键值对数据结构,它和Map主要有以下区别:
1.WeakMap只接受对象(null除外)和 Symbol 值作为键名,不接受其他类型的值作为键名。
2.WeakMap其键值对之间是弱引用关系。对于WeakMap中的键,如果除了WeakMap之外没有任何其他强引用指向该键所在的对象,则垃圾回收器可以在下一次垃圾回收周期中回收这个键所指向的对象,即使WeakMap还持有该键值对。而Map键值对之间是强引用关系。这意味着只要Map本身还在内存中,Map中的键和值都会被垃圾回收机制视为有效引用,因此不会被回收。
3.WeakMap没有迭代器,不可以枚举。
4.WeakMap只有get()、set()、has()、delete()四种方法可用
下面是一个创建WeakMap简单的示例:
<script>
const map = new WeakMap();
// 创建一个对象作为键
const key = { name: "老王" };
map.set(key, "这是老王的数据");
console.log(map.get(key)); // 这是老王的数据
</script>
2.2 使用场景
因为能被垃圾回收的性质,我们可以在一些希望键值能影响生命周期的地方使用,例如:
我们在Vue中,我们要通过指令动态创建多个Div,div的数量被存储在WeakMap中,当Div需要被销毁时,删除在WeakMap的键值对。示例。。。还没写好,以后再补上。