Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值
Map 和 Object 的区别
|  | Map | Object | 
| 意外的键 | Map 默认情况不包含任何键。只包含显式插入的键 | 一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。 | 
| 键的类型 | 一个 Map 的键可以是任意值,包括函数、对象或任意基本类型。 | 一个 Object 的键必须是一个 String 或是 Symbol | 
| 键的顺序 | Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。 | 一个 Object 的键是无序的 注意:自 ECMAScript 2015 规范以来,对象确实保留了字符串和 Symbol 键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。 | 
| Size | Map 的键值对个数可以轻易地通过 size 属性获取 | Object 的键值对个数只能手动计算 | 
| 迭代 | Map 是 iterable 的,所以可以直接被迭代 | 迭代一个 Object 需要以某种方式获取它的键然后才能迭代。 | 
| 性能 | 在频繁增删键值对的场景下表现更好。 | 在频繁添加和删除键值对的场景下未作出优化。 | 
Map 类型特点和创建方式
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | let obj = {
 1: "李四",
 "1": "张三",
 };
 console.log(obj);
 
 
 let map = new Map();
 
 map.set("name", "李四");
 
 map.set(1, "数字");
 
 map.set(function() {}, "方法作为键名");
 
 map.set({}, "对象键名");
 console.log(map);
 
 | 
Map 类型的增删改查
- map.set增加
- map.delete(key)删除单个
- map.clear()删除全部
- map.get(key)查询单个
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | let map = new Map();
 map.set("name", "李四");
 map.set("age", "10");
 
 
 
 console.log(map.delete("age"));
 
 
 
 
 console.log(map.get("name"));
 
 console.log(map);
 
 | 
遍历 Map 类型
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | let map = new Map();map.set("name", "李四");
 map.set("age", "15");
 
 
 console.log(map.keys());
 
 
 console.log(map.values());
 
 
 console.log(map.entries());
 
 
 for (let key of map.keys()) {
 console.log(key);
 }
 
 
 for (let val of map.values()) {
 console.log(val);
 }
 
 
 for (let [key, val] of map.entries()) {
 console.log(key, val);
 }
 
 
 map.forEach((item, key) => {
 console.log(item, key);
 });
 
 | 
Map 类型转换
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | let map = new Map();map.set("name", "李四");
 map.set("age", "18");
 
 
 console.log([...map]);
 
 let newmap = [...map];
 
 let newarr = newmap.filter((item) => {
 return item[1].includes("李四");
 });
 
 let map2 = new Map(newarr);
 
 console.log(...map2.keys());
 
 | 
Map 类型操作 DOM 节点
| 12
 
 | <div name="非常棒">songzhengxiang</div><div name="这都被你发现了">千万别点我</div>
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | let map = new Map();
 
 let divs = document.querySelectorAll("div");
 
 divs.forEach((item) => {
 map.set(item, {
 name: item.getAttribute("name"),
 });
 });
 
 
 map.forEach((content, divitem) => {
 divitem.addEventListener("click", () => {
 alert(content.name);
 });
 });
 console.log(map);
 
 | 
Map 控制表单提交
| 12
 3
 4
 5
 6
 7
 8
 
 | <form action="" onsubmit="return post()">服务协议
 <input type="checkbox" error="请勾选协议" />
 权限管理
 <input type="checkbox" error="请勾选权限管理" />
 
 <input type="submit" value="提交" />
 </form>
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | function post() {
 let error = document.querySelectorAll("[error]");
 let map = new Map();
 error.forEach((item) => {
 map.set(item, {
 error: item.getAttribute("error"),
 state: item.checked,
 });
 });
 let newmap = [...map];
 
 return newmap.every(
 ([div, checkbox]) => checkbox.state || alert(checkbox.error)
 );
 }
 
 | 
WeakMap 的使用
WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的
| 12
 3
 4
 5
 6
 7
 
 | let weakmap = new WeakMap();const o1 = {};
 const o2 = function() {};
 weakmap.set(o1, "37");
 weakmap.set(o2, undefined);
 
 console.log(weakmap);
 
 | 
WeakMap 弱引用类型体验
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | let obj = {name: "lisi",
 };
 let weakmap = new WeakMap();
 weakmap.set(obj, "lisi");
 
 console.log(weakmap);
 obj = null;
 
 console.log(weakmap);
 
 setTimeout(() => {
 
 console.log(weakmap);
 }, 1000);
 
 | 
使用 Map 开发选课组件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 | .kecheng {width: 300px;
 float: left;
 }
 
 .xuanran {
 width: 300px;
 float: left;
 margin-top: 11px;
 }
 
 ul {
 list-style: none;
 }
 
 ul > li {
 border: 2px solid red;
 margin: 2px;
 width: 200px;
 padding: 5px;
 position: relative;
 }
 
 li > a {
 text-decoration: none;
 position: absolute;
 right: 15px;
 background-color: green;
 color: white;
 width: 21px;
 text-align: center;
 border-radius: 3px;
 }
 .plck {
 padding-left: -5px;
 padding-top: 20px;
 }
 .plck > span {
 background-color: green;
 color: white;
 padding: 3px;
 border-radius: 2px;
 margin: 5px;
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | <div class="main">
 <div class="kecheng">
 <ul>
 <li><span>css</span> <a href="javascript:;">+</a></li>
 <li><span>html</span> <a href="javascript:;">+</a></li>
 <li><span>js</span> <a href="javascript:;">+</a></li>
 <li><span>vue</span> <a href="javascript:;">+</a></li>
 <li><span>小程序</span> <a href="javascript:;">+</a></li>
 </ul>
 </div>
 
 <div class="xuanran">
 <div class="info">当前一共选择了0门课程</div>
 <div class="plck"></div>
 </div>
 </div>
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 
 | class todo {constructor() {
 
 this.map = new Map();
 
 this.lis = document.querySelectorAll("li");
 
 this.info = document.querySelector(".info");
 
 this.plck = document.querySelector(".plck");
 }
 run() {
 this.lis.forEach((item) => {
 item.querySelector("a").addEventListener("click", (event) => {
 
 if (!item.getAttribute("select")) {
 
 item.setAttribute("select", true);
 
 this.map.set(item, {
 name: item.querySelector("span").innerHTML,
 });
 
 event.target.style.backgroundColor = "red";
 
 event.target.innerHTML = "-";
 event.target.style.transition = "0.5s";
 } else {
 
 item.removeAttribute("select");
 
 this.map.delete(item);
 
 event.target.style.backgroundColor = "green";
 
 event.target.innerHTML = "+";
 event.target.style.transition = "0.5s";
 }
 
 let infohtml = document.querySelector(".info");
 
 infohtml.innerHTML = `当前一共选择了${this.map.size}门课程`;
 
 let plck = document.querySelector(".plck");
 plck.innerHTML = "";
 
 this.map.forEach((name, lis) => {
 plck.innerHTML += `<span>${name.name}</span>`;
 });
 });
 });
 }
 }
 new todo().run();
 
 |