WeakMap类型

作者: 小雪洁 | 来源:发表于2020-04-26 22:33 被阅读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

相关文章

  • WeakMap类型

    效果如下:

  • 深拷贝

    准备 WeakMap类型WeakMaps 保持了对键名所引用的对象的弱引用,而且WeakMap 只接受对象作为键名...

  • 凭415日常吗

    weakMan需要竞争上岗才能积累技术吗 WeakMap的key只能是Object类型吗 WeakMap更有效的垃...

  • WeakMap的学习与应用场景

    WeakMap 是什么? WeakMap 与 Map 类似,也是生成 键值对的组合,但是有区别:1.WeakMap...

  • WeakMap的理解

    let obj = {id: 1}const weakMap = new WeakMap([[obj, 'sina...

  • 深度复制对象的属性---Js深拷贝

    完整实现方法1 Es6新增的Symbol由于不是引用类型,只有深拷贝WeakMap和WeakSet由于无法遍历,无...

  • WeakMap和WeakSet

    WeakMap 只接受对象最为键名(null 除外),不接受其他类型的值作为键名; 键名是弱引用,键值可以是任意的...

  • Set WeakSet Map WeakMap

    Set SetWeak Map WeakMap

  • es6 WeakMap - 2019-01-13

    2019-01-13 创建 WeakMap与Map的区别: WeakMap只接受对象作为键名(null除外),不接...

  • javascript高级程序设计7

    Map(映射)和weakMap(弱映射)1.MapMap是一种新的集合类型,我觉得就是object的加强版,obj...

网友评论

    本文标题:WeakMap类型

    本文链接:https://www.haomeiwen.com/subject/bzpswhtx.html