Map是一组键值对的结构,函数、对象、基本类型都可以作为键或值。
1.声明定义及基本操作
- set()方法相当于set中的add()方法,用于向集合中添加元素,当参数为一个值时,参数作为键名,有两个参数时,作为键值对。参数为Map中已有的键名时,则会修改对应的value值。参数为引用类型或者数字类型。
var m1 = new Map();
m1.set('name');
m1.set(function f1() { }, 18);
m1.set('sex', 'man');
m1.set({},{})
console.log(m1);;
接受一个数组作为参数,该数组的成员是一个表示键值对的数组。
let m = new Map([ ['陕西', '西安'], ['湖南', '长沙'] ]); console.log(m.get('陕西')); //西安
2.使用set向map中添加元素支持链式操作
链式操作(也称为链式调用或链式语法)是一种常见的编程模式,它通过在对象上连续调用方法来实现复杂的操作。每个方法都返回一个可以再次被调用的对象,从而形成一种“链式”结构。
let map = new Map();
let obj = {
name: "小明"
};
map.set(obj, "小明儿子").set("name", "小明孙子").set("age",1234);
console.log(map.entries());
注意看结果,虽然是链式操作,但是key-value都是相互独立的,不过是可以更方便的添加数据而已.
3.map长度console.log(map.size);
4.判断元素是否存在,返回true或false
map.has('age');
5.读取元素
map.get('age');
请看下面的例子:
var m1 = new Map();
m1.set(function f1() {}, 18);
console.log(m1);
console.log(m1.get(function f1() {}));
在这种情况下,为什么我们打印Map可以看到function f1() {} => 18;为什么get(function f1() {})显示的却是undefined ?
这是因为每次创建一个新的函数,都会创建一个新的对象。即使两个函数的内容完全相同,它们也被视为两个不同的对象。所以,当你试图使用 m1.get(function f1() { }) 获取值时,你实际上是在创建一个新的函数对象,而这个新的函数对象并没有在你的Map m1 中。
如果你想要通过函数来获取值,你需要将函数保存到一个变量中,然后使用这个变量来设置和获取值。例如:
var m1 = new Map();
var f1 = function() { };
m1.set(f1, 18);
console.log(m1.get(f1)); // 输出:18
6.删除元素
清除单个map.delete('age');
清除全部map.clear();
2.遍历map
使用 keys()/values()/entries() 都可以返回可遍历的迭代对象
let map1 = new Map([["陕西", "西安"], ["河北", "石家庄"]]);
console.log(map1.keys()); //MapIterator {'陕西', '河北'}
console.log(map1.values()); //MapIterator {'西安', '石家庄'}
console.log(map1.entries()); //MapIterator {'陕西' => '西安', '河北' => '石家庄'}
换一种方式实现entries的效果.
let map1 = new Map([["陕西", "西安"], ["河北", "石家庄"]]);
for(const [key,value] of map1){
console.log(`${key} => ${value}`);
}
3.实例(勾选所有的checkbox才可以进行提交)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="" onsubmit="return post()">
规则1:
<input type="checkbox" name="1" mes="请选择1">
规则2:
<input type="checkbox" name="2" mes="请选择2">
<input type="submit" name="" id="">
</form>
</body>
</html>
<script>
function post(){
let inputs = document.querySelectorAll('[mes]');
let map = new Map();
inputs.forEach(item =>{
map.set(item, {
mes: item.getAttribute("mes"),
status: item.checked
})
});
return [...map].every(([item,value]) => {
value.status || alert(value.mes);
return value.status
})
}
</script>
代码解释
value.status || alert(value.mes);
这一行其实是利用了 '||'运算的短路特性(有一个为真,第二个就不运行了,直接跳过)
4.WeakMap介绍
在JavaScript中,Map和WeakMap都是内置的数据结构,用于存储键值对。它们之间的主要区别在于以下几点:
- 键类型的限制:在Map中,键可以是任意类型的值(包括基本类型和对象引用),而在WeakMap中,键只能是对象引用。
var m1 = new WeakMap([[function f1() { }, '函数']]);
console.log(m1);
var m2 = new WeakMap([['name', '张三']]);
console.log(m2);
- 垃圾回收机制:在Map中,如果某个键不再被引用,它仍然会被Map引用,并且不会被垃圾回收。而在WeakMap中,如果某个键不再被引用,它会被自动从WeakMap中删除,这也是WeakMap的一个特性,可以避免内存泄漏。
- 迭代:在Map中,可以使用 Map.prototype.keys() 、 Map.prototype.values() 和 Map.prototype.entries() 等方法来迭代Map中的键、值或键值对,而在WeakMap中,由于键是对象引用,无法直接迭代键或值。
- 功能:Map相比WeakMap提供了更多的功能,比如可以获取Map的大小(使用 Map.prototype.size 属性),可以通过键获取值(使用 Map.prototype.get() 方法),可以遍历Map中的键值对等。而WeakMap相对简单,只提供了 WeakMap.prototype.get() 、 WeakMap.prototype.set() 、 WeakMap.prototype.has() 和 WeakMap.prototype.delete() 等基本操作。
Map适用于一般的键值对存储需求,而WeakMap更适用于需要存储对象关联信息且不希望干扰垃圾回收的场景(也就是说数据如果除WeakMap使用,外部无人访问时可以被回收)。
WeakMap类似于WeakSet,请查看javascript 中Set与WeakSet 是什么?一文)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。