zoukankan      html  css  js  c++  java
  • JavaScript Set

    Set

      用于存储任何类型的唯一值,无论是基本类型还是引用类型。

      只有值没有键

      严格类型检测存储,字符串数字不等同于数值型数字

      存储的值具有唯一性

      遍历顺序是添加的顺序,方便保存回调函数

      其实Set类型更多的是操作数据,而并非存储。

    基础知识

    声明定义

      以下示例演示出如何使用Set类型存储数据。

    <script>"use strict";
    
            let set = new Set([1, "1", 1, 1, 1, 2, 3, 4, 5, "2"])  // 严格类型检测 1 != "1"
    
            console.log(set instanceof Set);  // true
    
            console.log(set);  // set(7) {1, "1", 2, 3, 4, 5, "2"}
    </script>

    添加元素

      以下示例将演示如何将任意值元素添加进set容器中,使用add()方法进行添加元素的操作。

    <script>"use strict";
    
            let set = new Set()
    
            set.add(1);
    
            set.add(["一","二","三"]);
    
            set.add('1');
    
            console.log(set); // Set(3) {1, Array(3), "1"}
            
    </script>

    获取数量

      使用size属性获取set容器中的元素个数。

    <script>"use strict";
    
            let set = new Set()
    
            set.add(1);
    
            set.add(["一","二","三"]);
    
            set.add('1');
    
            console.log(set); // Set(3) {1, Array(3), "1"}
    
            console.log(set.size);  // 3
    </script>
     

    元素检测

      使用has()方法检测元素是否存在。

    <script>"use strict";
    
            let set = new Set()
    
            set.add(1);
    
            set.add(["一", "二", "三"]);
    
            set.add('1');
    
            console.log(set); // Set(3) {1, Array(3), "1"}
    
            console.log(set.has(["一", "二", "三"]));  // 由于是不同的引用地址,故结果为 false
            
            let array = ["四", "五", "六"];
    
            set.add(array)
    
            console.log(set.has(array));  // 现在的引用地址一致,结果为 true
    </script>

    删除元素

      使用delete()方法删除单个元素,返回值为boolean类型。

    <script>"use strict";
    
            let set = new Set()
    
            set.add(1);
    
            set.add(["一", "二", "三"]);
    
            set.add('1');
    
            console.log(set); // Set(3) {1, Array(3), "1"}
     
            let res = set.delete(1); // 值类型,可以直接删除
    
            console.log(res); // true 代表删除成功
    
            res = set.delete(["一", "二", "三"])  // 引用类型,不可以直接删除
    
            console.log(res); // false 代表删除失败
    </script>

    清空容器

      使用clear()方法可使set容器清空。

    <script>"use strict";
    
            let set = new Set()
    
            set.add(1);
    
            set.add(["一", "二", "三"]);
    
            set.add('1');
    
            set.clear();
    
            console.log(set.size);  // 0
    </script>

    数组转换

      转换数据类型是为了更好的操纵数据,可以使用...语法或者Array.form()方法将set转换为array

      我们可以充分的结果set去重的特性,以及array丰富的操作方法来任意操纵我们的元素。

      如下,我们将set类型转换为了数组。

    <script>"use strict";
    
            let set = new Set(["云崖先生", "男", 18])
    
            let array = [...set];
    
            console.log(array);  // (3) ["云崖先生", "男", 18]
    
            console.log(array instanceof Array); // true
    </script>

      将数组转换为set,可以充分利用去重特性。

    <script>"use strict";
    
            let array = new Array(1, 1, 1, 2, 2, 3, 4, 5);
    
            array = new Set(array);  // 去重
    
            array = Array.from(array)
    
            console.log(array instanceof Array); // true
    
            console.log(array); // (5) [1, 2, 3, 4, 5]
    </script>

    遍历操作

    迭代器创建

      使用 keys()/values()/entries() 都可以返回迭代对象,因为set类型只有值所以 keysvalues 方法结果一致。

    <script>
    
            "use strict";
    
            let set = new Set(["一", "二", "三", "四", "五"]);
    
            let iter_keys = set.keys();
    
            let iter_values = set.values();
    
            let iter_entries = set.entries();
    
            console.log(iter_keys);
    
            console.log(iter_values);
    
            console.log(iter_entries);
            
    </script>

    image-20200729172338715

    forEach

      使用forEach来循环set容器。

    <script>
    
            "use strict";
    
            let set = new Set(["一", "二", "三", "四", "五"]);
    
    
            set.forEach(function (index, value) {
                    console.log(index, value);
            });
    
    
    </script>

    image-20200729172549381

    for/of

      也可使用for/of进行循环。

    <script>
    
            "use strict";
    
            let set = new Set(["一", "二", "三", "四", "五"]);
    
    
            for (let i of set) {
                    
                    console.log(i);
            }
    
    </script>

    image-20200729172734276

    多集合操作

    交集

      交集代表set1set2共有的部分。

    <script>
    
            "use strict";
    
            let set1 = new Set(["一", "二", "三", "四", "五"]);
            let set2 = new Set(["三", "四", "五", "六", "七"]);
    
            let new_set = new Set(
    
                    Array.from(set1).filter(function (value) { 
                            return set2.has(value) 
    
                            })
            );
    
            console.log(new_set);  // Set(3) {"三", "四", "五"}
    
    </script>

    差集

      差集代表一个集合有,另一个集合没有的部分。

    <script>
    
            "use strict";
    
            let set1 = new Set(["一", "二", "三", "四", "五"]);
            let set2 = new Set(["三", "四", "五", "六", "七"]);
    
            let new_set = new Set(
    
                    Array.from(set1).filter(function (value) {
                            return !set2.has(value)
    
                    })
            );
    
            console.log(new_set);  // Set(3) Set(2) {"一", "二"}
    
    </script>

    并集

      将两个集合合并成一个集合,多余的元素会被剔除,这就是并集。

    <script>
    
            "use strict";
    
            let set1 = new Set(["一", "二", "三", "四", "五"]);
            let set2 = new Set(["三", "四", "五", "六", "七"]);
    
            let new_set = new Set([...set1,...set2]);
    
            console.log(new_set);  // Set(7) {"一", "二", "三", "四", "五", "六", "七"}
    
    </script>

    WeakSet

      WeakSet结构同样不会存储重复的值,它的成员必须只能是对象类型的值。

    • 垃圾回收不考虑WeakSet,即被WeakSet引用时引用计数器不加一,所以对象不被引用时不管WeakSet是否在使用都将删除

    • 因为WeakSet 是弱引用,由于其他地方操作成员可能会不存在,所以不可以进行forEach( )遍历等操作

    • 也是因为弱引用,WeakSet结构没有keys()values()entries()等方法和size属性

    • 因为是弱引用所以当外部引用删除时,希望自动删除数据时使用 Weakset

    声明定义

      WeakSet中只能保存容器类型的对象,即引用类型,不能保存值类型。

    <script>
    
            "use strict";
    
            let array = [1,2,3];
    
            let dict = {"k1":"v1","k2":"v2"};
    
            let set = new WeakSet([array,dict]);  // 在 WeakSet中只能保存容器类型的对象,即引用类型。不能保存值类型
    
            console.log(set);
    
    </script>

      保存值类型会抛出异常。

    <script>
    
            "use strict";
    
            let array = [1,2,3];
    
            let dict = {"k1":"v1","k2":"v2"};
    
            let symbol = new Symbol();  // 值类型
    
            let set = new WeakSet([array,dict,symbol]);  // 在 WeakSet中只能保存容器类型的对象,即引用类型。不能保存值类型
    
            console.log(set); // Uncaught TypeError: Symbol is not a constructor
    
    </script>

    操作方法

    方法说明
    add() 添加一个引用类型对象
    delete() 删除一个引用类型对象
    has() 判断是否存在一个引用类型对象

    垃圾回收

      对于标记清除法来说,存在于WeakSet中的对象并不会为其增加引用计数,因此也被称之为弱引用。

      WeakSet中对象的外部引用计数为0后,垃圾回收机制将清理 WeakSet容器中的该对象,这会使得WeakSet容器中该对象将被移除。 

    <script>
    
            "use strict";
    
            let array = [1, 2, 3];
    
            let dict = { "k1": "v1", "k2": "v2" };
    
            let set = new WeakSet([array, dict]);
    
            console.log(set);  // array还在里面
    
            array = null;  // 清理,引用计数为0
    
            setInterval(() => {
    
                    console.log(set);  // array 不在了
    
            }, 3000);
    
    </script>

    image-20200729175844897

    作用详解

      根据WeakSet这个特性,我们可以用它来保存一下经常存取的数据。

      当对象被删除后,我们不用管WeakSet容器中是否含存有该数据。

      示例如下:

      将标签节点全部放入集合中,当在点击的时候添加类并且移出集合设置透明度,当再次点击的时候又将标签移入集合即可。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
            <link rel="stylesheet" href="//at.alicdn.com/t/font_1953712_h1wr0ianmf5.css">
            <style>
                    body {
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            flex-flow: column wrap;
                            height: 100vh;
                            width: 100vw;
                    }
    
    
                    input {
                            border: none;
                            height: 20px;
    
    
                    }
    
                    div {
                            border: 1px solid #ddd;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            margin-bottom: 10px;
                            padding: 0 5px;
                            width: 200px;
                            height: 30px;
    
                    }
    
                    div input {
                            flex: 1;
                    }
    
                    div input:focus {
                            outline: none;
                    }
    
    
                    div i {
                            background-color: rgba(0, 255, 96, 5);
                            padding: 2px;
                            border-radius: 10%;
    
                    }
    
                    i.iconfont {
                            font-size: 12px;
                    }
    
                    .hidden {
                            opacity: .5;
                    }
            </style>
    </head>
    
    
    <body>
            <div>
                    <input type="text"><i class="iconfont icon-shanchu"></i>
            </div>
            <div>
                    <input type="text"><i class="iconfont icon-shanchu"></i>
            </div>
            <div>
                    <input type="text"><i class="iconfont icon-shanchu"></i>
            </div>
            <div>
                    <input type="text"><i class="iconfont icon-shanchu"></i>
            </div>
    
    
    </body>
    <script>
    
            "use strict";
    
            let divs = document.querySelectorAll("div");
    
            let set = new WeakSet([...divs]);
    
            divs.forEach(function (ele) {
    
                    ele.childNodes[2].addEventListener("click", function (param) {
                            if (set.has(this.parentNode)) {
                                    set.delete(this.parentNode);
                                    this.parentNode.classList.add('hidden');
                            }
                            else {
                                    set.add(this.parentNode);
                                    this.parentNode.classList.remove("hidden");
                            }
    
                    })
            })
    
    </script>
    
    </html>
  • 相关阅读:
    清除浮动解决父元素高度塌陷问题
    canvas画动图
    vue实现列表的循环滚动
    localStorage读写操作
    angularJS快速入门
    python模块
    python函数式编程
    python高级特性
    Flask 快速入门
    JQuery Ajax
  • 原文地址:https://www.cnblogs.com/Yunya-Cnblogs/p/13398972.html
Copyright © 2011-2022 走看看