Map与WeakMap讲解与选课组件开发
作者:互联网
Map与WeakMap方法讲解与简单的选课组件开发
Map与WeakMap
Map类型的特点与创建
想要了解Map,首先来看看对象吧,拿对象做对比来展开对Map的学习。
对于对象来说,对象当中的键只能是字符串!!
let obj = {
1:'lihuina',
"1":"lhn"
}
console.log(obj); //{1: "lhn"}
定义对象时,虽然可以将键定义为数字,但是打印出来只有下面的那一个,上面的数字1会被自动转换为字符串,下面的就把上面的覆盖了
let hd= {
//这里需要将obj用[]括起来,这样取到的才是我们定义的对象,否则只是一个普通的键名
[obj]:"baby"
}
// 要想取到obj里面的值
// 根据打印hd出来的结果,我们需要
console.log(hd["[object Object]"]);
// 或者
console.log(hd[obj.toString()]);
打印出来的结果如图所示
但是Map,什么都可以作为键名
// Map创建
let map = new Map();
//不管是字符串,函数,对象,数值,都可以作为键名
map.set("name","lihuina");
map.set(function(){},"baby");
map.set({},"jjjj");
map.set(1,"ggggg");
打印出来点开之后的结果,也能更清晰地看出Map是以键值对的方式存在
Map支持链式操作
例如字符串的链式操作(连续调用方法):
let str = 'abc';
console.log(str.toLowerCase().substr(1,1));
在Map中中的链式操作(例如可以连续向Map中添加键值对)
let map = new Map([['name','lihuina'],['age',18]]);
map.set("sina","xinlang").set("baidu","百度").set("blog","博客");
console.log(map);
Map增删改查
let map = new Map();
添加元素 set()
let obj = {
name:"李四"
};
map.set(obj,'lisi');
map.set('name','lhn');
获取元素 get()
console.log(map.get(obj));
判断是否存在 has()
console.log(map.has(obj));
删除元素 delete()
console.log(map.delete(obj));
console.log(map);
清空元素 clear()
map.clear();
console.log(map);
遍历Map
let map = new Map([['name','lihuina'],['age',18]]);
map.set("address","jgsu");
获取所有键 keys()
console.log(map.keys());
获取所有值 values()
console.log(map.values());
获取所有的键值对 entries()
console.log(map.entries());
循环
forof
// 循环键
for (const key of map.keys()) {
console.log(key);
}
// 循环值
for (const value of map.values()) {
console.log(value);
}
// 循环键值对
for (const [key,value] of map.entries()) {
console.log([key,value]);
}
foreach
map.forEach((key,value) => {
console.log(key,value);
});
Map类型转换
let map = new Map([['name','lihuina'],['age',18]]);
map => 数组
点语法
console.log([...map]);
也可以单独转换键或者值
console.log([...map.keys()]);
console.log([...map.values()]);
举例:
想把值为lihuina的单独拿出来变成一个新的集合,其他的不变
// 先变为数组,然后过滤器找出想要的
let newArr = [...map].filter(item => {
return item.includes('lihuina');
});
// 再变回集合
let edu = new Map(newArr);
console.log(...edu.values()); // lihuina
Map类型管理DOM节点
let map = new Map();
document.querySelectorAll('div').forEach(item=>{
map.set(item,{
// 键名是div,内容就是属性值,可以往里面保存任何与DOM节点有关的信息
content:item.getAttribute('name')
});
});
console.log(map);
点击的时候弹出提示消息内容
// 点击的时候弹出提示消息内容
map.forEach((config,elem)=>{
// console.log(config);
// console.log(elem);
elem.addEventListener("click",()=>{
alert(config.content);
});
})
例:使用map类型控制表单提交
点击提交时便会调用post方法,将勾选项中的内容添加到map中,将对象作为键值,键为表单DOM元素,值为错误信息以及是否被选中的状态,Map类型可以方便我们存储这两种类型的数据。
<body>
<form action="" onsubmit="return post()">
接受协议:
<input type="checkbox" name="agreement" error='请接受协议'>
我是学生:
<input type="checkbox" name="student" error='网站只对学生开放'>
<input type="submit">
</form>
<script>
function post(){
let map = new Map();
let inputs = document.querySelectorAll("[error]");
// console.log(inputs);
inputs.forEach(item=>{
map.set(item,{
error:item.getAttribute('error'),
status:item.checked
});
});
// 将map转换为数组,使用every方法,只有全都勾选,状态全为真时才允许提交,否则会弹出错误信息
// 返回状态信息,有一个不勾选就返回false,就不允许提交
// 如果只传一个参数elem则会得到一个数组,第一个是元素,第二个是json对象,这样取的话,
// 如果想获得json对象的话,还得elem[1]这种来取
// 这里可以使用解构,第二个为config,这样就config直接得到我们想要的数据了
return [...map].every(([elem,config])=>{
// 如果状态为真就什么都不做,为假的话就弹出里面的错误消息
config.status || alert(config.error);
return config.status;
})
// console.log(map);
// return false;
}
</script>
</body>
WeakMap
WeakMap里面的键只能是对象,像weakset的值必须得是对象
let map = new WeakMap();
// 键为字符串时会报错
// map.set("name","lihuina"); // Invalid value used as weak map key at WeakMap.set (<anonymous>)
// 键为引用类型(数组,对象等)不会报错
map.set([],"lihuina"); //WeakMap {Array(0) => "lihuina"}
console.log(map);
DOM元素是对象
<body>
<!-- DOM元素是对象 -->
<div>lihuina</div>
<div>baby</div>
<script>
let divs = document.querySelectorAll('div');
let map = new WeakMap();
divs.forEach(item=>map.set(item,item.innerHTML));
console.log(map);
</script>
</body>
WeakMap的增删改查
// 基本语法
let arr = []; //数组是引用类型
let map = new WeakMap();
// 添加
map.set(arr,'lihuina');
// 删除
map.delete(arr);
// 判断
console.log(map.has(arr));
// values keys size forof 都用不了
console.log(map);
弱类型特性
let hd = {name:"lihuina"};
// 首先让hd和cms变量都指向这个对象
let cms = hd;
let map = new WeakMap();
// 再让map中的键指向这个对象
map.set(hd,"lihuina.com");
// 让hd和cms都不指向这个对象了
hd = null;
cms = null;
//这时应该垃圾回收机制已经来了
// 这时候打印 map时还是会显示出存在的亚子
console.log(map);
// 用计时器来看一下吧
// 浏览器版本不同,有的浏览器用setTimeOut计时器就可以一下子显示出来,我的浏览器需要过时间久一点点才可以,便用这个方法来显示啦,直接看打印结果图就明白啦
setInterval(function(){
console.log(map);
},1000);
-
清空hd和cms之后map还是会打印出来,刚开始清空的时候,WeakMap还没有感知到
-
过一段时间之后,系统自检之后会发现这个问题,然后把他修正
-
因为这个问题的产生,所以WeakMap不让我们使用values keys size forof 这些方法
-
设置定时器之后,会发现过一段时间就没有了
-
所以利用这个特性,使用WeapMap保存数据的时候,不需要人工清理,只要外面的数据变了,他就会自己消失了
-
所以WeakMap主要是为了保存受外部影响的数据
例:使用WeakMap开发选课组件
效果图看最后,代码解释就放在注释里面咯
(没有css代码,可以自己设计)
可以自己运行调试一下
<body>
<div class="ke">
<ul>
<li><span> lihuina</span><a href="javascript:;">+</a></li>
<li><span> baby</span><a href="javascript:;">+</a></li>
<li><span> lihuina.com</span><a href="javascript:;">+</a></li>
</ul>
</div>
<div class="text">
<strong id="count">共选了0门课</strong>
<p id="lists"></p>
</div>
<script>
class Lesson{
constructor(){
this.lis = document.querySelectorAll("ul>li");
// console.log(this.lis);
this.countElem = document.getElementById('count');
this.listsElem = document.getElementById('lists');
// console.log(this.countElem);
// console.log(this.listsElem);
this.map = new WeakMap();
}
run(){
this.lis.forEach(li=>{
li.querySelector('a').addEventListener('click',event=>{
// console.log(li);
// console.log(event.target.parentElement);
const a = event.target;
// console.log(this);
const state = li.getAttribute('select');
if(state){
li.removeAttribute('select');
this.map.delete(li);
a.innerHTML = "+";
a.style.backgroundColor = 'green';
}else{
this.map.set(li);
li.setAttribute('select',true);
a.innerHTML = "-";
a.style.backgroundColor = 'red';
}
// console.log(this.map);
this.render();
});
});
}
lists(){
return [...this.lis].filter(li=>{
return this.map.has(li);
}).map(li=>{
return `<span>${li.querySelector('span').innerHTML }</span>`;
}).join(" ");
}
count(){
return [...this.lis].reduce((count,li)=>{
return count += (this.map.has(li)?1:0);
},0);
}
render(){
this.countElem.innerHTML = `共选了${this.count()}门课`;
this.listsElem.innerHTML = this.lists();
}
}
new Lesson().run();
</script>
</body>
文章来源于观看后盾人课程的笔记(自己做的),有问题欢迎纠正
标签:Map,set,console,log,map,选课,WeakMap,let 来源: https://blog.csdn.net/weixin_49138751/article/details/118655393