最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 你真的了解ES6的Set和Map吗

    正文概述 掘金(兔子零84)   2021-04-04   407

    map/set

    之前在学习 ES6 的时候,看到 SetMap,不知道其应用场景有哪些,只觉得很多时候会用在数组去重和数据存储,后来慢慢才领悟到 Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结构。

    Set

    Set 本身是一个构造函数,用来生成 Set 数据结构。Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。Set 对象允许你存储任何类型的值,无论是原始值或者是对象引用。它类似于数组,但是成员的值都是唯一的,没有重复的值。

    const s = new Set()
    [2, 3, 5, 4, 5, 2, 2].forEach((x) => s.add(x))
    for (let i of s) {
      console.log(i)
    }
    // 2 3 5 4
    

    Set 中的特殊值

    Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:

    • +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复
    • undefinedundefined 是恒等的,所以不重复
    • NaNNaN 是不恒等的,但是在 Set 中认为 NaNNaN 相等,所有只能存在一个,不重复。

    Set 的属性:

    • size:返回集合所包含元素的数量
    const items = new Set([1, 2, 3, 4, 5, 5, 5, 5])
    items.size // 5
    

    Set 实例对象的方法

    • add(value):添加某个值,返回 Set 结构本身(可以链式调用)。
    • delete(value):删除某个值,删除成功返回 true,否则返回 false
    • has(value):返回一个布尔值,表示该值是否为 Set 的成员。
    • clear():清除所有成员,没有返回值。
    s.add(1).add(2).add(2)
    // 注意2被加入了两次
    
    s.size // 2
    
    s.has(1) // true
    s.has(2) // true
    s.has(3) // false
    
    s.delete(2)
    s.has(2) // false
    

    遍历方法

    • keys():返回键名的遍历器。
    • values():返回键值的遍历器。
    • entries():返回键值对的遍历器。
    • forEach():使用回调函数遍历每个成员。

    由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以 keys 方法和 values 方法的行为完全一致。

    let set = new Set(['red', 'green', 'blue'])
    
    for (let item of set.keys()) {
      console.log(item)
    }
    // red
    // green
    // blue
    
    for (let item of set.values()) {
      console.log(item)
    }
    // red
    // green
    // blue
    
    for (let item of set.entries()) {
      console.log(item)
    }
    // ["red", "red"]
    // ["green", "green"]
    // ["blue", "blue"]
    

    Array 和 Set 对比

    • ArrayindexOf 方法比 Sethas 方法效率低下
    • Set 不含有重复值(可以利用这个特性实现对一个数组的去重)
    • Set 通过 delete 方法删除某个值,而 Array 只能通过 splice。两者的使用方便程度前者更优
    • Array 的很多新方法 mapfiltersomeevery 等是 Set 没有的(但是通过两者可以互相转换来使用)

    Set 的应用

    1、Array.from 方法可以将 Set 结构转为数组。

    const items = new Set([1, 2, 3, 4, 5])
    const array = Array.from(items)
    

    2、数组去重

    // 去除数组的重复成员
    ;[...new Set(array)]
    
    Array.from(new Set(array))
    

    3、数组的 mapfilter 方法也可以间接用于 Set

    let set = new Set([1, 2, 3])
    set = new Set([...set].map((x) => x * 2))
    // 返回Set结构:{2, 4, 6}
    
    let set = new Set([1, 2, 3, 4, 5])
    set = new Set([...set].filter((x) => x % 2 == 0))
    // 返回Set结构:{2, 4}
    

    4、实现并集 (Union)、交集 (Intersect) 和差集

    let a = new Set([1, 2, 3])
    let b = new Set([4, 3, 2])
    
    // 并集
    let union = new Set([...a, ...b])
    // Set {1, 2, 3, 4}
    
    // 交集
    let intersect = new Set([...a].filter((x) => b.has(x)))
    // set {2, 3}
    
    // 差集
    let difference = new Set([...a].filter((x) => !b.has(x)))
    // Set {1}
    

    weakSet

    WeakSet 结构与 Set 类似,也是不重复的值的集合。

    • 成员都是数组和类似数组的对象,若调用 add() 方法时传入了非数组和类似数组的对象的参数,就会抛出错误。
    const b = [1, 2, [1, 2]]
    new WeakSet(b) // Uncaught TypeError: Invalid value used in weak set
    
    • 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏。
    • WeakSet 不可迭代,因此不能被用在 for-of 等循环中。
    • WeakSet 没有 size 属性。

    Map

    Map 中存储的是 key-value 形式的键值对, 其中的 keyvalue 可以是任何类型的, 即对象也可以作为 keyMap 的出现,就是让各种类型的值都可以当作键。Map 提供的是 “值-值”的对应。

    Map 和 Object 的区别

    1. Object 对象有原型, 也就是说他有默认的 key 值在对象上面, 除非我们使用 Object.create(null)创建一个没有原型的对象;
    2. Object 对象中, 只能把 StringSymbol 作为 key 值, 但是在 Map 中,key 值可以是任何基本类型(String, Number, Boolean, undefined, NaN….),或者对象(Map, Set, Object, Function , Symbol , null….);
    3. 通过 Map 中的 size 属性, 可以很方便地获取到 Map 长度, 要获取 Object 的长度, 你只能手动计算

    Map 的属性

    • size: 返回集合所包含元素的数量
    const map = new Map()
    map.set('foo', ture)
    map.set('bar', false)
    map.size // 2
    

    Map 对象的方法

    • set(key, val): 向 Map 中添加新元素
    • get(key): 通过键值查找特定的数值并返回
    • has(key): 判断 Map 对象中是否有 Key 所对应的值,有返回 true,否则返回 false
    • delete(key): 通过键值从 Map 中移除对应的数据
    • clear(): 将这个 Map 中的所有元素删除
    const m = new Map()
    const o = { p: 'Hello World' }
    
    m.set(o, 'content')
    m.get(o) // "content"
    
    m.has(o) // true
    m.delete(o) // true
    m.has(o) // false
    

    遍历方法

    • keys():返回键名的遍历器
    • values():返回键值的遍历器
    • entries():返回键值对的遍历器
    • forEach():使用回调函数遍历每个成员
    const map = new Map([
      ['a', 1],
      ['b', 2],
    ])
    
    for (let key of map.keys()) {
      console.log(key)
    }
    // "a"
    // "b"
    
    for (let value of map.values()) {
      console.log(value)
    }
    // 1
    // 2
    
    for (let item of map.entries()) {
      console.log(item)
    }
    // ["a", 1]
    // ["b", 2]
    
    // 或者
    for (let [key, value] of map.entries()) {
      console.log(key, value)
    }
    // "a" 1
    // "b" 2
    
    // for...of...遍历map等同于使用map.entries()
    
    for (let [key, value] of map) {
      console.log(key, value)
    }
    // "a" 1
    // "b" 2
    

    数据类型转化

    Map 转为数组

    let map = new Map()
    let arr = [...map]
    

    数组转为 Map

    Map: map = new Map(arr)
    

    Map 转为对象

    let obj = {}
    for (let [k, v] of map) {
      obj[k] = v
    }
    

    对象转为 Map

    for( let k of Object.keys(obj)){
      map.set(k,obj[k])
    }
    

    Map的应用

    在一些 Admin 项目中我们通常都对个人信息进行展示,比如将如下信息展示到页面上。传统方法如下。

    <div class="info-item">
      <span>姓名</span>
      <span>{{info.name}}</span>
    </div>
    <div class="info-item">
      <span>年龄</span>
      <span>{{info.age}}</span>
    </div>
    <div class="info-item">
      <span>性别</span>
      <span>{{info.sex}}</span>
    </div>
    <div class="info-item">
      <span>手机号</span>
      <span>{{info.phone}}</span>
    </div>
    <div class="info-item">
      <span>家庭住址</span>
      <span>{{info.address}}</span>
    </div>
    <div class="info-item">
      <span>家庭住址</span>
      <span>{{info.duty}}</span>
    </div>
    

    js 代码

    mounted() {
      this.info = {
        name: 'jack',
        sex: '男',
        age: '28',
        phone: '13888888888',
        address: '广东省广州市',
        duty: '总经理'
      }
    }
    

    我们通过 Map 来改造,将我们需要显示的 label 和 value 存到我们的 Map 后渲染到页面,这样减少了大量的html代码

    <template>
      <div id="app">
        <div class="info-item" v-for="[label, value] in infoMap" :key="value">
          <span>{{label}}</span>
          <span>{{value}}</span>
        </div>
      </div>
    </template>
    

    js 代码

    data: () => ({
      info: {},
      infoMap: {}
    }),
    mounted () {
      this.info = {
        name: 'jack',
        sex: '男',
        age: '28',
        phone: '13888888888',
        address: '广东省广州市',
        duty: '总经理'
      }
      const mapKeys = ['姓名', '性别', '年龄', '电话', '家庭地址', '身份']
      const result = new Map()
      let i = 0
      for (const key in this.info) {
        result.set(mapKeys[i], this.info[key])
        i++
      }
      this.infoMap = result
    }
    

    WeakMap

    WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。

    • 只接受对象作为键名(null 除外),不接受其他类型的值作为键名
    • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
    • 不能遍历,方法有 getsethasdelete

    总结

    Set

    • 是一种叫做集合的数据结构(ES6新增的)
    • 成员唯一、无序且不重复
    • [value, value],键值与键名是一致的(或者说只有键值,没有键名)
    • 允许储存任何类型的唯一值,无论是原始值或者是对象引用
    • 可以遍历,方法有:adddeletehasclear

    WeakSet

    • 成员都是对象
    • 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏
    • 不能遍历,方法有 adddeletehas

    Map

    • 是一种类似于字典的数据结构,本质上是键值对的集合
    • 可以遍历,可以跟各种数据格式转换
    • 操作方法有:setgethasdeleteclear

    WeakMap

    • 只接受对象作为键名(null 除外),不接受其他类型的值作为键名
    • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
    • 不能遍历,方法有 getsethasdelete

    起源地下载网 » 你真的了解ES6的Set和Map吗

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元