Map与WeakMap类型在JavaScript中的使用

map类型特点与创建方法:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>

    <script>
        // 对象的键名会自动转为字符串
        // let obj = {
        //     1: 'cyy1',
        //     '1': 'cyy2'
        // };
        // console.log(obj);

        // 对象的键名是对象时,会自动转为字符串
        // 读取时也要先转为字符串再读取
        //         let obj = {
        //             name: 'cyy'
        //         };
        //         let obj2 = {
        //             obj: 'cyy2',
        //             [obj]: 'cyy3'
        //         };
        //         console.log(obj2);
        //         console.log(obj2[obj.toString()]);

        // map类型,什么都可以作为键,键名可以是任何类型
        // let map = new Map();
        // map.set('name', 'cyy');
        // map.set(function() {}, 'cyy2');
        // map.set({}, 'cyy3');
        // map.set(1, 'cyy4');
        // console.log(map);

        // 构造函数创建时加入数据
        let map = new Map([
            ['name', 'cyy'],
            ['age', 18]
        ]);
        console.log(map);

        // 支持链式操作
        let str = 'cyy';
        let str2 = str.toUpperCase().substr(1, 2);
        console.log(str2);

        map.set('11', 11).set('22', 22);
        console.log(map);
    </script>
</body>

</html>

map类型增删改查操作:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>

    <script>
        let obj = {
            name: 'cyy'
        };
        let map = new Map();
        map.set(obj, 'obj');
        console.log(map.has(obj));
        console.log(map);
        console.log(map.get(obj));
        console.log(map.delete('abc'));
        console.log(map.delete(obj));
        map.clear();
        console.log(map);
    </script>
</body>

</html>

遍历map类型数据:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>

    <script>
        let map = new Map([
            [1, 11],
            [2, 22]
        ]);
        // console.log(map.keys());
        // console.log(map.values());
        // console.log(map.entries());

        // for (let k of map.keys()) {
        //     console.log(k);
        // }
        // for (let v of map.values()) {
        //     console.log(v);
        // }
        // for (let e of map.entries()) {
        //     console.log(e);
        // }
        // for (let [k, v] of map.entries()) {
        //     console.log(`${k}--${v}`);
        // }

        map.forEach((item, key) => {
            console.log(item + '--' + key);
        })
    </script>
</body>

</html>

map类型转换操作:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>

    <script>
        let map = new Map([
            ['name', 'cyy'],
            ['age', '18']
        ]);
        // console.log(...map);
        // console.log([...map]);
        // console.log([...map.entries()]);
        // console.log([...map.keys()]);
        // console.log([...map.values()]);

        // let arr = [...map].filter(item => item[1].includes('cyy'));
        let arr = [...map].filter(item => {
            return item[1].includes('cyy');
        });
        // console.log(arr);
        let new_map = new Map(arr);
        console.log(new_map);
        console.log(new_map.values());
        // ...是展开语法
        console.log(...new_map.values());
    </script>
</body>

</html>

map类型管理DOM节点:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>
    <div name="cyy1">cyy1</div>
    <div name="cyy2">cyy2</div>

    <script>
        let map = new Map();
        let divs = document.querySelectorAll('div');
        divs.forEach(item => {
            // 往map中压入数据
            map.set(item, {
                content: item.getAttribute('name')
            });
        });
        // console.log(map);
        map.forEach((config, elem) => {
            // console.log(config, elem);
            elem.addEventListener('click', function() {
                console.log(config.content);
            });
        })
    </script>
</body>

</html>

使用map类型控制网站表单提交:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>
    <form action="#" onsubmit="return post()">
        接受协议:
        <input type="checkbox" name="agreement" error="请接受协议"> 我是学生:
        <input type="checkbox" name="student" error="网站只对学生开放">
        <input type="submit" value="提交">
    </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
                });
            });
            // console.log(map);
            return [...map].every(([elem, config]) => {
                // 短路操作,前面为真,则不会执行后面
                // 前面会假,则执行后面
                config.status || alert(config.error);
                return config.status;
                // console.log(config);
            });

        }
    </script>
</body>

</html>

WeakMap的语法使用:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>
    <div>cyy</div>
    <div>cyy2</div>

    <script>
        // WeakMap的键只能是引用对象
        // let map = new WeakMap();
        // map.set('name');
        // console.log(map);

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

        // let map = new WeakMap();
        // let divs = document.querySelectorAll('div');
        // divs.forEach(item => map.set(item, item.innerHTML));
        // console.log(map);

        // WeakMap也是弱引用类型
        // let arr = [];
        // let map = new WeakMap();
        // map.set(arr, 'cyy');
        // map.delete(arr);
        // console.log(map.has(arr));
        // console.log(map);

        // 弱引用类型,values、keys、entries、迭代循环都用不了
        let map = new WeakMap();
        // console.log(map.keys());

        for (const iterator of map) {
            console.log(iterator);
        }
    </script>
</body>

</html>

WeakMap弱引用类型体验:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <style>

    </style>
</head>

<body>

    <script>
        let a = { name: 'cyy' };
        let b = a;
        let map = new WeakMap();
        map.set(a, 'cuu2');
        console.log(map);
        a = null;
        b = null;
        console.log(map);
        setTimeout(function () {
            console.log(map);
        }, 1000);
    </script>
</body>

</html>

使用WeakMap开发选课组件:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        main {
            width: 100%;
            display: flex;
            flex: 1;
        }

        section {
            border: 2px solid #ddd;
            width: 50%;
            padding: 10px;
        }

        ul {
            list-style: none;
        }

        li {
            padding: 10px;
            border: 2px solid orange;
            margin-bottom: 5px;
            position: relative;
        }

        a {
            display: inline-block;
            position: absolute;
            right: 10px;
            width: 20px;
            height: 20px;
            background: green;
            color: white;
            text-decoration: none;
            line-height: 20px;
            text-align: center;
        }

        #list span {
            background: green;
            border-radius: 5px;
            padding: 5px;
            color: white;
            margin: 5px;
        }

        #list {
            margin-top: 20px;
        }
    </style>
</head>

<body>
    <main>
        <section>
            <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>
        </section>
        <section>
            <strong id="count">共选了2门课</strong>
            <p id="list">
                <!-- <span>111</span> -->
            </p>
        </section>
    </main>

    <script>
        class Lesson {
            // 构造函数
            constructor() {
                this.lis = document.querySelectorAll('li');
                this.countElem = document.getElementById('count');
                this.listElem = document.getElementById('list');
                // console.log(this.lis, this.countElem, this.listElem);
                this.map = new WeakMap();
            }
            run() {
                this.lis.forEach(li => {
                    li.querySelector('a').addEventListener('click', event => {
                        let a = event.target;
                        // console.log(li);
                        // console.log(event.target.parentElement);
                        const state = li.getAttribute('select');
                        if (state) {
                            // 移除
                            li.removeAttribute('select');
                            this.map.delete(li);
                            a.style.backgroundColor = 'green';
                            a.innerHTML = '+';
                        } else {
                            // 添加
                            li.setAttribute('select', true);
                            this.map.set(li);
                            a.style.backgroundColor = 'red';
                            a.innerHTML = '-';
                        }
                        // console.log(this.map);
                        this.render();
                    });
                })
            }
            render() {
                this.countElem.innerHTML = `共选了${this.count()}门课`;
                // console.log(this.count());
                this.listElem.innerHTML = this.list();
            }
            count() {
                return [...this.lis].reduce((count, li) => {
                    return count += this.map.has(li) ? 1 : 0;
                }, 0);
            }
            list() {
                let lis = [...this.lis].filter(li => {
                    return this.map.has(li);
                }).map(li => {
                    return `<span>${li.querySelector('span').innerHTML}</span>`;
                }).join('');
                // console.log(lis);
                return lis;
            }
        }
        new Lesson().run();
    </script>
</body>

</html>
(0)

相关推荐