js系列-Set集合和WeakSet弱引用

Set

Set对象是值的集合, Set中的元素只会出现一次,即 Set 中的元素是唯一的,无论是基本类型还是对象引用。

    let set = new Set([1, 1, '1', { name: 'zhang' }, [1, 2, 3]]);
    console.log(set);//Set(4) {1, "1", {…}, Array(3)}

通过上面简单的定义我们可以发现几个问题: 

  • 虽然Set定义是{..}对象,但只有值没有key键名
  • 是严格类型检测如字符串数字不等于数值型数字,即1和'1'不等
  • 和数组不同的是数组有重复项,而Set的值是唯一的

属性 

size

 Set 对象中的值的个数,类似数组length属性

    let set = new Set([1, '1', { name: 'zhang' }, [1, 2, 3]]);
    console.log(set.size);//4

方法

add

Set对象尾部添加一个元素。返回Set对象。

    let set = new Set(['a','b']);
    console.log(set.add('c'));//Set(3) {"a", "b", "c"}

delete

删除单个元素,返回值为boolean类型

    let set = new Set(['a','b']);
    console.log(set.delete('b'));//true
    console.log(set.delete('c'));//false

clear

移除Set对象内的所有元素,无返回值

    let set = new Set(['a','b']);
    console.log(set.clear());//undefined

has

检查元素是否存在,返回值为boolean类型

    let set = new Set(['a','b']);
    console.log(set.has('b'));//true
    console.log(set.has('c'));//false

遍历

    let set = new Set(['a','b']);
    for (const item of set) {
        console.log(item);//'a'  'b'
    }

    for (const item of set.keys()) {
        console.log(item); // 'a' 'b'
    }
    for (const item of set.values()) {
        console.log(item); // 'a' 'b'
    }
    for (const item of set.entries()) {
        console.log(item); // ["a", "a"]  ["b", "b"]
    }

数组转换

数组章节我们已经讲过转换方法有两种,点语法Array.form 静态方法,可以将set转换为数组,就可以使用数组的一些便捷方法。

    let set = new Set(['a', 'b']);
    console.log(Array.from(set));//["a", "b"]
    console.log([...set]); //["a", "b"]

转换成数组后,使用数组的filter方法过滤set数据:

    //使用数组方法,取小于3的数据
    let set = new Set([1, 2, 3, 4, 5]);
    set = new Set([...set].filter(item => item < 3));
    console.log(set);//Set(2) {1, 2}

    //使用set方法,同样取小于3的数据
    let set1 = new Set([1, 2, 3, 4, 5]);
    set1.forEach(item => {
      if (item >= 3) {
        set1.delete(item);
      }
    })
    //或则
    // for (const item of set1) {
    //   if (item >= 3) {
    //     set1.delete(item);
    //   }
    // }
    console.log(set1);

数组去重

我们另一个用的比较多的就是,把数组转Set去除重复元素;当然这是指接收到的外部数据存在重复元素需要去重,如果是我们自己定义的话,可以直接定义为Set类型。

    //外部传过来的数据
    let arr = [1, 2, 3, 4, 5, 3, 1];
    arr = [...new Set(arr)];
    console.log(arr);//[1, 2, 3, 4, 5]

数组中的并集/交集/差集/补集

    let arr1 = [1, 2, 3, 8, 9];
    let arr2 = [2, 8, 5, 6];

    //并集(即两个数组都存在的元素)
    console.log(arr1.concat(arr2.filter(item => !arr1.includes(item))));//[1, 2, 3, 8, 9, 5, 6]
    //交集(即两数组共同拥有的元素),以上实例交集为[2, 8]
    console.log(arr1.filter(item => arr2.includes(item)));// [2, 8]
    //差集(数组arr1中有,数组arr2中没有的元素)
    console.log(arr1.filter(item => !arr2.includes(item)));// [1, 3, 9]
    //补集(去除arr1和arr2中都有的元素之后的所有元素)
    console.log(arr1.filter(item => !arr2.includes(item)).concat(
      arr2.filter(item => !arr1.includes(item))
    ))//[1, 3, 9, 5, 6]

Set的并集/交集/差集/补集

    let set1 = new Set([1, 2, 3, 9]);
    let set2 = new Set([2, 5]);
    console.log(set1, set2)
    //并集
    console.log(new Set([...set1, ...set2]))//Set(5) {1, 2, 3, 9, 5}
    //交集
    console.log(new Set([...set1].filter(item => set2.has(item))))//Set(1) {2}
    //差集
    console.log(new Set([...set1].filter(item => !set2.has(item))))//Set(3) {1, 3, 9}
    //补集
    console.log(new Set([...set1].filter(item => !set2.has(item)).concat(
      [...set2].filter(item => !set1.has(item))
    )))//Set(4) {1, 3, 9, 5}

WeakSet

WeakSet 和 Set 类似,都是不重复的值的集合,但是和 Set 有两点不同:

  1. WeakSet 的成员只能是对象
  2. WeakSet 的对象都是弱引用

即WeakSet 中对对象的引用不会被考虑进垃圾回收机制,即只要没有其他的对象引用该对象,则该对象就会被回收,而不管它在不在 WeakSet,​ (由于这个特性,所以 WeakSet 适合临时存放一组对象和跟对象绑定的信息) ​

3. WeakSet 没有size属性,没法遍历(故没有 forEach 方法)
因为 WeakSet 中有多少个成员取决于(没有其他对象对WeakSet成员的引用后)垃圾回收机制有没有运行,运行前后可能成员的个数是不一样的,而垃圾回收机制何时运行是不可预测的,所以 ES6 规定 WeakSet 不能被遍历

WeakSet 的应用场景/ 好处

用于存储DOM节点,而不用担心这些节点从文档移除时会引发内存泄露
即可以用来避免内存泄露的情况

WeakSet 的语法

  1. WeaSet 是一个构造函数,通过 new WeakSet() 可生成一个实例

WeakSet作为构造函数:可接收数组或类数组对象作为其参数:则数组的所有成员 都会自动成为 WeakSet 对象的成员

注:
(1) 数组的成员只能是对象(因为WeakSet的成员只能是对象)
(2) 成为 WeakSet 的成员的是数组的成员,而不是数组本身。

WeakSet 有三个方法:add, delete, has
WeakSet.prototype.add(value) 向WeakSet 实例添加一个成员
WeakSet.prototype.delete(value) 清除 WeakSet 实例的指定成员
WeakSet.prototype.has(value) 判断某个值是否在WeakSet 实例中,返回布尔值

你可能感兴趣的:(JavaScript,javascript,Set,WeakSet)