Map and WeakMap explanation and course selection component development

Map and WeakMap

Characteristics and creation of Map type

To understand Map, first look at the objects. Compare the objects to learn about Map.

For an object, the key in the object can only be a string!!

let obj = {
            1:'lihuina',
            "1":"lhn"
        }
console.log(obj); //{1: "lhn"}

When defining an object, although the key can be defined as a number, only the following one will be printed. The number 1 above will be automatically converted into a string, and the following will overwrite the above one

let hd= {
			//Here, we need to enclose obj with [] so that we can get the object we defined, otherwise it is just an ordinary key name
            [obj]:"baby"
        }
// To get the value in obj
// According to the printed hd results, we need
console.log(hd["[object Object]"]);
// perhaps
console.log(hd[obj.toString()]);

The printed results are shown in the figure

But Map, anything can be used as a key name

// Map creation
let map = new Map();
//Whether it is a string, function, object or value, it can be used as a key name
map.set("name","lihuina");
map.set(function(){},"baby");
map.set({},"jjjj");
map.set(1,"ggggg");

After printing the results, you can more clearly see that the Map exists in the form of key value pairs

Map supports chain operation

For example, chain operation of string (continuous call method):

let str = 'abc';
console.log(str.toLowerCase().substr(1,1));

Chain operation in Map (for example, you can continuously add key value pairs to Map)

let map = new Map([['name','lihuina'],['age',18]]);
map.set("sina","xinlang").set("baidu","Baidu").set("blog","Blog");

console.log(map);

Add, delete, modify and query Map

let map = new Map();

Add element set()

let obj = {
        name:"Li Si"
	};
map.set(obj,'lisi');
map.set('name','lhn');

Get element ()

console.log(map.get(obj));

Determine whether has() exists

 console.log(map.has(obj));

Delete element

console.log(map.delete(obj));
console.log(map);

Clear element ()

map.clear();
console.log(map);

Traverse Map

let map = new Map([['name','lihuina'],['age',18]]);
map.set("address","jgsu");

Get all keys()

 console.log(map.keys());

Get all values()

 console.log(map.values());

Get all key value pairs entries()

console.log(map.entries());

loop

forof
// Cyclic key
for (const key of map.keys()) {
            console.log(key);
        }
// Cyclic value
for (const value of map.values()) {
            console.log(value);
        }
// Circular key value pair
for (const [key,value] of map.entries()) {
            console.log([key,value]);
        }

foreach
 map.forEach((key,value) => {
            console.log(key,value);
        });

Map type conversion

let map = new Map([['name','lihuina'],['age',18]]);

Map = > array

Point grammar

console.log([...map]);

You can also convert keys or values separately

console.log([...map.keys()]);
console.log([...map.values()]);

give an example:

If you want to take out the value lihuina alone and turn it into a new set, the others remain unchanged

// First it becomes an array, and then the filter finds what you want
let newArr = [...map].filter(item => {
    return item.includes('lihuina');
});
// Back to the set
let edu = new Map(newArr);
console.log(...edu.values());   // lihuina

Map type management DOM node

let map = new Map();
       document.querySelectorAll('div').forEach(item=>{
     map.set(item,{
        // The key name is div, and the content is the attribute value, which can store any information related to DOM nodes
        content:item.getAttribute('name')
    });
});
console.log(map);

A prompt message will pop up when clicking

 // A prompt message will pop up when clicking
map.forEach((config,elem)=>{
    // console.log(config);
    // console.log(elem);
    elem.addEventListener("click",()=>{
          alert(config.content);
    });
})

Example: use map type to control form submission

When you click Submit, you will call the post method to add the contents of the checked items to the map, take the object as the key value, the key is the form DOM element, and the value is the error information and whether it is selected. The map type can facilitate us to store these two types of data.

<body>
    <form action="" onsubmit="return post()">
        Acceptance agreement:
        <input type="checkbox" name="agreement" error='Please accept the agreement'>
        I am a student:
        <input type="checkbox" name="student" error='The website is only open to students'>
        <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
                });
            });
            
            // Convert the map into an array and use the every method. Only when all are checked and the status is all true can the submission be allowed, otherwise an error message will pop up
            // Return status information. If one is unchecked, it will return false, and submission is not allowed
            // If you pass only one parameter elem, you will get an array. The first is an element and the second is a json object,
            // If you want to get a json object, you have to use elem[1] to get it
            // Deconstruction can be used here, and the second is config, so config can directly get the data we want
            return [...map].every(([elem,config])=>{
                // If the status is true, do nothing. If it is false, an error message will pop up
                config.status || alert(config.error);
                return config.status;
            })
            // console.log(map);
            // return false;
        }
    </script>
</body>

WeakMap

The key in WeakMap can only be an object. For example, the value of weakset must be an object

let map = new WeakMap();
// An error will be reported when the key is a string
// map.set("name","lihuina"); // Invalid value used as weak map key      at WeakMap.set (<anonymous>)
// If the key is a reference type (array, object, etc.), no error will be reported
map.set([],"lihuina"); //WeakMap {Array(0) => "lihuina"} 
console.log(map); 

DOM elements are objects

<body>
    <!-- DOM Elements are objects -->
    <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>


Addition, deletion, modification and query of WeakMap

// Basic grammar
let arr = []; //Array is a reference type
let map = new WeakMap();
// add to
map.set(arr,'lihuina');
// delete
map.delete(arr);
// judge
console.log(map.has(arr));
// Values keys size for of
console.log(map);

Weak type characteristics

  let hd = {name:"lihuina"};
  		// First, let both hd and cms variables point to this object
        let cms = hd;
        let map = new WeakMap();
        // Then let the key in the map point to this object
        map.set(hd,"lihuina.com");
        // Let neither hd nor cms point to this object
        hd = null;
        cms = null;
        //At this time, the garbage collection mechanism should have come

		// At this time, when printing the map, the existing children will still be displayed
        console.log(map);
        // Let's take a look at it with a timer
        // The browser versions are different. Some browsers can display it all at once with the setTimeOut timer. My browser takes a little longer to display it. Just look at the print result directly
        setInterval(function(){
            console.log(map);
        },1000);
        

  • After clearing hd and cms, the map will still be printed. At the beginning of emptying, WeakMap did not perceive it

  • After a period of time, this problem will be found after the system self-test, and then it will be corrected

  • Because of this problem, WeakMap doesn't let us use values keys size for of these methods

  • After setting the timer, you will find that it will not be available for a period of time

  • Therefore, when using this feature to save data using WeapMap, there is no need to clean it manually. As long as the external data changes, it will disappear by itself

  • Therefore, WeakMap is mainly used to save externally affected data

Example: using WeakMap to develop course selection components

At the end of the rendering, the code explanation is put in the comments
(without css code, you can design it yourself)
You can run and debug it yourself

<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">A total of 0 courses were selected</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 = `Co selected ${this.count()}Course`;
                this.listsElem.innerHTML = this.lists();
            }
        }
        new Lesson().run();
    </script>
</body>



The article comes from the notes of watching the supporter course (made by yourself). If you have any problems, please correct them

Keywords: Javascript css3 html5 html css

Added by networkthis on Sat, 22 Jan 2022 03:47:09 +0200