JavaScript Set對象

JavaScript Set對象

Set

  用於存儲任何類型的惟一值,不管是基本類型仍是引用類型。css

 

  只有值沒有鍵html

  嚴格類型檢測存儲,字符串數字不等同於數值型數字數組

  存儲的值具備惟一性函數

  遍歷順序是添加的順序,方便保存回調函數flex

 

  其實Set類型更多的是操做數據,而並不是存儲。this

 

基礎知識

聲明定義


  如下示例演示出如何使用Set類型存儲數據。spa

 

<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()方法進行添加元素的操做。code

 

<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容器中的元素個數。orm

 

<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()方法檢測元素是否存在。cdn

 

<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容器內並不會保存該對象。

 

<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>
相關文章
相關標籤/搜索