WeakMap類(lèi)型

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>WeakMap</title>
    </head>
    <body>
        <div>haoxuejie</div>
        <div>yangdingchuan</div>
    </body>
    <script>
        //WeakMap類(lèi)型的數(shù)據(jù)鍵只能是對(duì)象
        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是節(jié)點(diǎn)對(duì)象
        
        //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類(lèi)型數(shù)據(jù)wmap中是否含有鍵為[]的元素
        console.log(wmap.has(arr));//true
        console.log(wmap.has([]));//false一定要注意map和WeakMap類(lèi)型的鍵是個(gè)引用
        
        
    </script>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>WeakMap弱類(lèi)型的特性</title>
    </head>
    <body>
    </body>
    <script>
        //WeakMap主要用來(lái)保存受外部影響的數(shù)據(jù)
        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開(kāi)發(fā)選課組件</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類(lèi),獲取li元素,獲取count元素
        //每次點(diǎn)擊+號(hào)后,a標(biāo)簽里背景變紅色符號(hào)變-,給li加上selected屬性,;
        //每次點(diǎn)擊-號(hào),a標(biāo)簽里背景變綠色符號(hào)變+,給li移除selected屬性,;
        //即給a標(biāo)簽添加點(diǎn)擊事件,如果這個(gè)a是-號(hào)(即父級(jí)li有selected屬性)a標(biāo)簽里背景變綠色符號(hào)變+,
        //如果這個(gè)a是+號(hào)(即父級(jí)li沒(méi)有selected屬性),就給li加上selected屬性,a標(biāo)簽里背景變紅色符號(hào)變-;
        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循環(huán),給里面的a加事件,獲取li的selected屬性,如果有就變綠變+
            //如果沒(méi)有就變紅變-
            //不使用箭頭函數(shù),以孫子函數(shù)的角度來(lái)解釋   :
            //若父親函數(shù)內(nèi)部還有孫子函數(shù),
            //孫子函數(shù)若要引用爺爺函數(shù)里定義的變量或方法
            //那在父親函數(shù)里要存爺爺?shù)膖his,如let _this=this;
            //孫子想訪(fǎng)問(wèn)父親外部爺爺?shù)淖兞浚陀眠@個(gè)_this.xxx;
            //如果不轉(zhuǎn)存,直接使用this只會(huì)在父親函數(shù)里找,父親外部的屬于爺爺?shù)淖兞?            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");
                        //狀態(tài)是-號(hào)已經(jīng)選中,點(diǎn)擊后要變+移除已選中,刪掉wm中的dom節(jié)點(diǎn)
                        if(selected){
                            li.removeAttribute("selected");
                            _this.wm.delete(li);
                            a.innerHTML="+";
                            a.style.background="#009999";
                        }else{ //狀態(tài)是+沒(méi)有選中,點(diǎn)擊后要變-號(hào)設(shè)置已選中,存儲(chǔ)wm的dom節(jié)點(diǎn)
                            //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()}門(mén)課`;
                this.updateLessons();
            }
            count(){
                //統(tǒng)計(jì)一共選了幾門(mén)課,用arr.reduce()函數(shù)
                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>`;
                        //上一行注釋中的語(yǔ)句就會(huì)出現(xiàn)重復(fù)往右邊框里加選中的課,
                        //因?yàn)槲颐看吸c(diǎn)擊都會(huì)觸發(fā)這個(gè)render(),都會(huì)遍歷一次左邊的li,
                        //第一次選中一個(gè)添加了,第二次遍歷我選了兩個(gè),又累加了所以會(huì)出現(xiàn)重復(fù);
                        //因此在每次遍歷前先清空一下html,記錄下我在這次點(diǎn)擊后遍歷的結(jié)果,
                        //循環(huán)結(jié)束后我把這個(gè)html賦值到p標(biāo)簽里
                        html+=`${li.querySelector("span").innerHTML}</br>`;
                    }
                });
                this.p.innerHTML=html;
            }
            
            //使用箭頭函數(shù)可以使函數(shù)內(nèi)部this與函數(shù)外部this指向一致
            //即父親的this就是指向爺爺?shù)膖his,孫子在自己的函數(shù)里就可以直接this到爺爺?shù)淖兞?            /* 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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容