WeakMap类型
2020-04-26 本文已影响0人
小雪洁
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WeakMap</title>
</head>
<body>
<div>haoxuejie</div>
<div>yangdingchuan</div>
</body>
<script>
//WeakMap类型的数据键只能是对象
let divs=document.querySelectorAll("div");
let wmap = new WeakMap();
divs.forEach(item=>{
wmap.set(item,item.innerHTML);
});
console.log(wmap);//
//WeakMap {div => "yangdingchuan", div => "haoxuejie"}
//其中div是节点对象
//WeakMap的方法只有set()、get()、has()、delete()
//添加元素
let arr=[]
wmap.set(arr,'hxj');
console.log(wmap);//{Array(0) => "hxj", div => "haoxuejie", div => "yangdingchuan"}
//获取元素
console.log(wmap.get(divs[0]));//取到的是值
//WeakMap类型数据wmap中是否含有键为[]的元素
console.log(wmap.has(arr));//true
console.log(wmap.has([]));//false一定要注意map和WeakMap类型的键是个引用
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WeakMap弱类型的特性</title>
</head>
<body>
</body>
<script>
//WeakMap主要用来保存受外部影响的数据
let hxj={name:'hxj'};
let wm1=new WeakMap();
wm1.set(hxj,30);
hxj=null;
console.log(wm1);//WeakMap {{…} => 30}
setTimeout(()=>{
console.log(wm1);
},5000);//WeakMap {}
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用WeakMap开发选课组件</title>
</head>
<style>
*{
padding: 0;
margin:0;
box-sizing: border-box;
}
body{
width:100vw;
height: 100vh;
display: flex;
justify-content: center;
padding: 10px;
}
body div{
width: 150px;
height: 100px;
border: solid #CCCCCC 1px;
margin: 5px;
}
div ul{
height: 100%;
list-style: none;
padding: 5px;
display:flex;
flex-direction: column;
justify-content: center;
}
div ul li{
width: 100%;
margin: 2px;
border: solid 2px #009688;
display: flex;
}
div ul li span{
flex: 1;
}
div ul li a{
text-decoration: none;
font-size: 1.2em;
background: #009999;
flex:0 0 20%;
text-align:center;
color: #FFFFFF;
}
div ul li a,span{
}
</style>
<body>
<div>
<ul>
<li><span>html</span><a href="javascript:;">+</a></li>
<li><span>css</span><a href="javascript:;">+</a></li>
<li><span>js</span><a href="javascript:;">+</a></li>
</ul>
</div>
<div>
<strong id="count"></strong>
<p id="lists"></p>
</div>
</body>
<script>
//lessons类,获取li元素,获取count元素
//每次点击+号后,a标签里背景变红色符号变-,给li加上selected属性,;
//每次点击-号,a标签里背景变绿色符号变+,给li移除selected属性,;
//即给a标签添加点击事件,如果这个a是-号(即父级li有selected属性)a标签里背景变绿色符号变+,
//如果这个a是+号(即父级li没有selected属性),就给li加上selected属性,a标签里背景变红色符号变-;
class lessons{
constructor() {
this.liEles= document.querySelectorAll("li");
this.countEle= document.getElementById("count");
this.wm=new WeakMap();
this.p=document.getElementById("lists");
}
run(){
this.addEvent();
}
//给li循环,给里面的a加事件,获取li的selected属性,如果有就变绿变+
//如果没有就变红变-
//不使用箭头函数,以孙子函数的角度来解释 :
//若父亲函数内部还有孙子函数,
//孙子函数若要引用爷爷函数里定义的变量或方法
//那在父亲函数里要存爷爷的this,如let _this=this;
//孙子想访问父亲外部爷爷的变量,就用这个_this.xxx;
//如果不转存,直接使用this只会在父亲函数里找,父亲外部的属于爷爷的变量
addEvent(){
let _this=this;
this.liEles.forEach(function(li){
let aEle=li.querySelector("a");
aEle.addEventListener("click",function(event){
let a= event.target;
let selected=li.getAttribute("selected");
//状态是-号已经选中,点击后要变+移除已选中,删掉wm中的dom节点
if(selected){
li.removeAttribute("selected");
_this.wm.delete(li);
a.innerHTML="+";
a.style.background="#009999";
}else{ //状态是+没有选中,点击后要变-号设置已选中,存储wm的dom节点
//console.log(this.wm);
_this.wm.set(li);
//console.log(_this.wm);
li.setAttribute("selected",true);
a.innerHTML="-";
a.style.background="red";
}
_this.render();
});
});
}
render(){
this.countEle.innerHTML=`共选择了${this.count()}门课`;
this.updateLessons();
}
count(){
//统计一共选了几门课,用arr.reduce()函数
return [...this.liEles].reduce((count,li)=>{
this.wm.has(li)?count++:"";
return count;
},0);
}
updateLessons(){
let html="";
[...this.liEles].filter(li=>{
if(this.wm.has(li)){
//this.p.innerHTML+=`${li.querySelector("span").innerHTML}</br>`;
//上一行注释中的语句就会出现重复往右边框里加选中的课,
//因为我每次点击都会触发这个render(),都会遍历一次左边的li,
//第一次选中一个添加了,第二次遍历我选了两个,又累加了所以会出现重复;
//因此在每次遍历前先清空一下html,记录下我在这次点击后遍历的结果,
//循环结束后我把这个html赋值到p标签里
html+=`${li.querySelector("span").innerHTML}</br>`;
}
});
this.p.innerHTML=html;
}
//使用箭头函数可以使函数内部this与函数外部this指向一致
//即父亲的this就是指向爷爷的this,孙子在自己的函数里就可以直接this到爷爷的变量
/* addEvent(){
this.liEles.forEach(li=>{
let aEle=li.querySelector("a");
aEle.addEventListener("click",(event)=>{
let a= event.target;
let selected=li.getAttribute("selected");
if(selected){
li.removeAttribute("selected");
this.wm.delete(li);
a.innerHTML="+";
a.style.background="green";
console.log(this.wm);
}else{
console.log(li);
this.wm.set(li);
console.log(a);
li.setAttribute("selected",true);
a.innerHTML="-";
a.style.background="red";
}
})
});
} */
};
let lesson= new lessons();
lesson.run();
</script>
</html>
效果如下:
选课小组件.gif