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
类型只有值因此 keys
与values
方法结果一致。
<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>
forEach
使用forEach
来循环set
容器。
<script> "use strict"; let set = new Set(["一", "二", "三", "四", "五"]); set.forEach(function (index, value) { console.log(index, value); }); </script>
for/of
也可以使用for/of
进行循环。
<script> "use strict"; let set = new Set(["一", "二", "三", "四", "五"]); for (let i of set) { console.log(i); } </script>
多集合操做
交集
交集表明set1
与set2
共有的部分。
<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>
做用详解
根据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>