WeakMap类型

<!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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容