javascript 中Set与WeakSet 是什么?

87 阅读4分钟

在JavaScript中,Set和WeakSet都是ES6引入的新的数据结构。(称其为集合)

1.简介

Set:

  • Set类似于数组,可以存储任何类型的唯一值(无重复),包括基本类型和复杂类型。
  • 可以使用new Set()构造函数创建一个Set。
  • 可以使用add()方法向Set添加元素。
  • 可以使用delete()和clear()方法从Set中移除元素。
  • 可以使用for...of循环或forEach()方法遍历Set的元素。
    WeakSet:
  • WeakSet只能包含对象,不能像Set那样包含任何类型的值。
  • WeakSet内的引用对对象是弱引用。如果没有其他对WeakSet中对象的引用存在,那么这些对象会被垃圾回收(即,WeakSet不是对象的强引用,并且不会阻止垃圾回收)
  • WeakSet不可迭代,也就是说不能用for...of循环遍历它的元素
  • WeakSet没有size属性,也没有clear、keys、values、entries、forEach等方法

2.Set基本使用

1.使用数组赋值:

let hd = new Set(['零跑c10', '银河L7']);
console.log(hd.values()); //{"零跑c10", "银河L7"}

2.Set 中是严格类型约束的,下面的数值1与字符串1属于两个不同的值

let set = new Set();
set.add(1);
set.add("1");
console.log(set); //Set(2) {1, "1"}

3.使用 add 添加元素,不允许值重复

let hd = new Set();
hd.add('1');
hd.add('2');
hd.add('2')

console.log(hd); 

4.获取元素数量

let hd = new Set(['1', '2']);
console.log(hd.size); //2

5.检测元素是否存在

let setVal = new Set();
setVal.add(1);
console.log(setVal.has(1));//true

6.删除元素
使用delete删除元素

let setVal = new Set();
setVal.add(1);
setVal.add(2);
setVal.add(3);
setVal.delete(2);
console.log(setVal);//Set(2) {1, 3}

console.log(setVal.delete(123));//false

使用clear删除Set中的全部

let setVal = new Set();
setVal.add(1);
setVal.add(2);
setVal.add(3);

setVal.clear();
console.log(setVal);//Set(0) {size: 0}

3.Set使用场景举例

1.可以将Set转为数组,使用数组的方法
例如:去掉Set中小于3的元素

let setVal = new Set();
setVal.add(1);
setVal.add(2);
setVal.add(3);

setVal = [...setVal].filter(item => {
    return item > 2;
});

console.log(setVal);[3]

2.Set值不能重复,所有可以利用这个特性对数组进行去重操作
例入:

let arr = [1,2,3,3,2,1,67,67,99];
arr = new Set(arr);
arr = [...arr];
console.log(arr);//[1, 2, 3, 67, 99]

3.还是利用Set值唯一这个特点,如果页面中需要输入不唯一的值,保存的方式可以不使用数组,而使用集合Set
例如:将每次输入的值,鼠标失去焦点后如果不存在则显示在屏幕上:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            padding: 200px;
        }
      
        * {
            padding: 0;
            margin: 0;
        }
      
        ul {
            list-style: none;
            width: 200px;
            padding-top: 20px;
        }
      
      </style>
</head>
<body>
    <input type="text">
    <ul></ul>
  </body>
  <script>
    let obj = {
        words: new Set(),
        set keyword(word) {
            this.words.add(word);
        },
        show() {
            let ul = document.querySelector('ul');
            ul.innerHTML = '';
            this.words.forEach((item) => {
                ul.innerHTML += ('<li>' + item + '</li>');
            })
        }
    }
  
    document.querySelector('input').addEventListener('blur', function () {
        console.log('打印this', this);
        obj.keyword = this.value;
        obj.show();
    });
  </script>
4.交集,并集,差集
    let a = new Set([1,2,3]);
    let b = new Set([3,4,5]);
    
    //交集
    let c = [...a].filter(item => b.has(item));
    console.log(c);

    //并集
    let d = new Set([...a,...b]);
    console.log(d);

    //差集
    let e = [...a].filter(item => !b.has(item));e
    console.log(e);

4.WeakSet基本使用

1.声明定义

WeakSet值必须是对象类型
new WeakSet([["1,2"], ["3"]]);
DOM节点也可以保存在WeakSet

let Wset = new WeakSet();
document.querySelectorAll("button").forEach(item => Wset.add(item));
2.基本指令
const hd = new WeakSet();
const arr = ["1"];
//添加操作
hd.add(arr);
console.log(hd.has(arr));

//删除操作
hd.delete(arr);

//检索判断
console.log(hd.has(arr));
3.垃圾回收

引用类型垃圾回收原理简单说就是没人使用的情况下就将其删除

将数组放在WeakSet中,就是弱引用;
也就是说引用计数器不会叠加,请看下面这个例子:

const WSet = new WeakSet();
let arr = ["劳动节"];
WSet.add(arr);
console.log('WeakSet', WSet.has(arr));

arr = null;
console.log('After arr = null',WSet); //WeakSet {Array(1)}

setTimeout(() => {
  console.log('1s after WeakSet',WSet); //WeakSet {}
}, 1000);

可以发现,当我将数组arr 置为 null 后,外部不在使用arr了,当垃圾回收时对象被删除,这时WakeSet也就没有记录了。
也是因为这个特性,会导致WeakSet有可能保存系统还没来的及删除的垃圾数据,所以WeakSet没有keys(),循环这些操作。

前端的世界总是在不断变化,作为开发者,我们需要保持好奇心和学习热情,不断探索新的技术,只有这样,我们才能在这个快速发展的时代中立于不败之地。Web Components 就是这样一个值得我们深入探索的领域,让我们拭目以待,它将给前端世界带来怎样的变革。

介绍一款程序员都应该知道的软件JNPF快速开发平台,很多人都尝试用过它,它是功能的集大成者,任何信息化系统都可以基于它开发出来。

这是一个基于 Java Boot/.Net Core 构建的简单、跨平台快速开发框架。前后端封装了上千个常用类,方便扩展;集成了代码生成器,支持前后端业务代码生成,实现快速开发,提升工作效率;框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用;后端框架支持 Vue2、Vue3。如果你有闲暇时间,可以做个知识拓展。

看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~