• 面试官:“ES6中新增的Set方法去重你会吗?”我:“看文章就知道了”


    在这里插入图片描述

    还在担心面试不通过吗?给大家推荐一个超级好用的刷面试题神器:牛客网,里面涵盖了各个领域的面试题库,还有大厂真题哦!

    赶快悄悄的努力起来吧,不苒在这里衷心祝愿各位大佬都能顺利通过面试。
    面试专栏分享,感觉有用的小伙伴可以点个订阅,不定时更新相关面试题:面试专栏
    在这里插入图片描述

    Set 的基本使用

    🍔前言

    ES6 之前,我们存储数的据结构主要有两种:数组、对象。
    在ES6中新增了另外两种数据结构SetMap,以及它们的另外形式WeakSetWeakMap
    就行了就让我们一起了解一下ES6中新增的两个数据结构吧。希望能给大家带来帮助,共同进步!

    🍏正文

    1. Set

    Set 是一个新增的数据结构,可以用来保存数据,类似于数组,但是和数组的区别是 元素不能重复

    1.1 Set的基本使用

    创建Set我们需要通过Set构造函数的方式去创建(暂时没有字面量创建方式):
    示例代码如下:

    // 使用构造函数方式创建Set
    var set = new Set()
    // add是Set的方法用于添加元素
    set.add(10)
    set.add(20)
    set.add(30)
    set.add(40)
    
    console.log(set) // Set { 10, 20, 30, 40 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    我们上面提到了,Set中的元素不能重复,给大家留个小问题,那么多个空数组可以重复吗?

    话不多说上代码:

    
    var setArr = new Set()
    
    let obj = {}
    
    setArr.add(10)
    setArr.add(50)
    setArr.add(10) // add 重复值 10
    // add 两个空对象
    setArr.add({})
    setArr.add({})
    // add 两个obj对象
    setArr.add(obj)
    setArr.add(obj)
    
    console.log(setArr) // Set { 10, 50, {}, {}, {} }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    不知道大家能不能看懂这段代码,我给大家解释一下

    1. 首先:我们可以很明显的看出来,添加的第二个10是没有添加进去的,因为Set不可以包含两个重复的值
    2. 其次:有的小伙伴要问了,怎么两个空对象可以重复呢?其实两个空对象看着一样其实是不一样的,两个空对象在存储空间中的内存地址是不一样的,可能第一个空对象的内存地址是0X100,第二个的内存地址可能0x200,所以会出现两个空数组。
    3. 最后:又有小伙伴要问了,为什么obj对象不能像第二段那样呢?因为两个obj对象的内存地址是一样的,他们两个是重复的,所以Set中只可以存在一个。

    1.2 Set 常见的属相和方法

    属性:
    + size:返回Set中元素的个数;
    方法:
    + add(value):添加某个元素,返回Set对象本身;
    + delete(value):从set中删除和这个值相等的元素,返回boolean类型;
    + has(value):判断set中是否存在某个元素,返回Boolean类型;
    + clear():清空set中所有的元素,没有返回值;
    + forEach(callback,[,thisArg]):通过forEach遍历set;

    完整示例代码如下所示,由于都比较简单就写在一块啦:

    const setArr = new Set()
    // 1.
    setArr.add(1)
    setArr.add(2)
    setArr.add(3)
    // 2。
    setArr.delete(2)  // Set { 1, 3 }
    // 3。
    console.log(setArr.has(3)) // true
    // 4.
    setArr.clear()
    // 5.
    setArr.forEach(item => {
        console.log(item)
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    for…of写法

    const setArr = new Set([1, 2, 3, 4, 5, 1])
    
    for (const iterator of setArr) {
        console.log(iterator)
    }
    /* 去重遍历
    1
    2
    3
    4
    5
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.3 应用场景:使用Set对数组进行去重(去除数组中的重复元素)

    首先告诉大家这个方法应用场景超级广泛并且效率很高(香得很)

    话不多说,代码交流:

    // 假设有一个数组arr 我们现在需要将数组进行去重操作
    const arr = [10, 20, 45, 39, 56, 45]
    
    // 方法一:
    const newArr1 = []
    arr.forEach(item => {
        if (newArr1.indexOf(item) == -1) {
            newArr1.push(item)
        }
    })
    console.log(newArr1) // [ 10, 20, 45, 39, 56 ]
    
    
    // 方法二:
    //new Set(arr)操作后的值(是set类型的): Set { 10, 20, 45, 39, 56 }
    const newArr2 = Array.from(new Set(arr))
    // const newArr2 = [...new Set(arr)]
    const newArr2 = (...new Set(arr))
    
    console.log(newArr2) // [ 10, 20, 45, 39, 56 ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • indexOf()也是一个进行数组操作的方法 此处用以是如果再newArr中没有找到item 就会返回-1,意味着没有该元素,将该元素放入newArr中实现去重操作
    • Array.from()将一个类数组对象或者可遍历对象转换成一个真正的数组
    • 方法二中将set类型转换为数组的方法还可以用展开运算符操作(注释代码即是)
      很明显可以看出来 ES6新增的Set方法更方便一点。

    2. WeakSet

    和Set类似的另外一个数据结构称之为WeakSet,也是内部元素不能重复的数据结构。

    和Set的区别的话就是:

    1. WeakSet中只能存放对象类型,不能存放基本数据类型;
    2. WeakSet对元素的引用是弱引用,如果没有其他引用对某个对象进行引用,那么GC(垃圾回收机制)可以对该对象进行回收。

    2.1 区别一:WeakSet中只能存放对象类型

    const weakSet1 = new WeakSet()
    
    const weakSet2 = new WeakSet()
    // 区别一:只能存储对象类型的数据(存储非对象类型会报错)
    
    
    weakSet.add(1) 
    console.log(weakSet1) // TypeError: Invalid value used in weak set
    
    weakSet.add({ name: 'jam' })
    console.log(weakSet2) // 不会报错
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2 区别二:WeakSet对元素的引用是弱引用

    • 强引用是指向内存申请一段存储空间,进行存储的引用类型的对象的引用,在对象获得的分配内存空间中不仅仅存放了对象的信息,还存放着该对象被引用的次数。
    • 弱引用是指不能确保其引用的对象不会被垃圾回收器回收的引用。一个对象若只被弱引用所引用,则被认为是不可访问的(或弱访问的),并因此可能在任何时刻被回收。

    2.3 WeakSet的使用场景

    场景描述:阻止非构造方法创建出来的对象调用内部方法running

    const weak = new WeakSet()
    class Person {
        constructor() {
            weak.add(this)
        }
    
        // person类的方法
        running () {
            if (!weak.has(this)) {
                throw new Error("禁止使用非构造方法创建出来的对象调用running方法")
            }
            console.log('running~~~', this)
        }
    
    }
    // 构造方法创建p
    let p = new Person()
    p.running() // running~~~ Person {}
    
    // 调用running方法 隐式绑定到obj对象上(非构造函数方法创建)
    let obj = { name: 'boo' }
    p.running.call(obj)  // Error: 禁止使用非构造方法创建出来的对象调用running方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    WeakSet 大家了解一下即可,上述这种应用场景很少应用到(几乎不会)


    🎃专栏分享:

    JavaScript相关面试题就更新到这里啦,相关 Web前端面试题 可以订阅专栏哦🥰
    专栏地址:《面试必看》
    面试刷题神器:牛客网


    名 言 警 句 : 说 能 做 的 , 做 说 过 的 \textcolor{red} {名言警句:说能做的,做说过的}

    原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下}

    👍 点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{green}{点赞,你的认可是我创作的动力!}

    ⭐️ 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{green}{收藏,你的青睐是我努力的方向!}

    ✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!}

  • 相关阅读:
    【ESP32 手机配网教程】
    【leetcode top100】两数相加。无重复字符的最长子串,盛水最多的容器,三数之和
    浅谈Elasticsearch 文档操作
    【微信小程序】三分钟学会小程序的列表渲染
    【iOS】计算器仿写
    【附源码】计算机毕业设计JAVA亦心化妆品网站
    新媒体营销实训解决方案
    交换机聚合配置 (H3C)
    网络安全宣传月安全团队需要知道的关于PKI的九件事
    【新版】软考 - 系统架构设计师(总结笔记)
  • 原文地址:https://blog.csdn.net/qq_49002903/article/details/126258741