你真的瞭解ES6的Set,WeakSet,Map和WeakMap嗎?

以前在學習 ES6 的時候,看到 SetMap,不知道其應用場景有哪些,只以爲不少時候會用在數組去重和數據存儲,後來慢慢才領悟到 Set 是一種叫作集合的數據結構,Map 是一種叫作字典的數據結構。javascript

本文在gitthub作了收錄:github.com/Michael-lzg…html

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 對象存儲的值老是惟一的,因此須要判斷兩個值是否恆等。有幾個特殊值須要特殊對待:vue

  • +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 方法的行爲徹底一致。java

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 的應用

一、Array.from 方法能夠將 Set 結構轉爲數組。webpack

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

二、數組去重git

// 去除數組的重複成員
;[...new Set(array)]

Array.from(new Set(array))

三、數組的 mapfilter 方法也能夠間接用於 Setgithub

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}

四、實現並集 (Union)、交集 (Intersect) 和差集web

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 相似,也是不重複的值的集合。vue-cli

  • 成員都是數組和相似數組的對象,若調用 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新增的)
  • 成員惟1、無序且不重複
  • [value, value],鍵值與鍵名是一致的(或者說只有鍵值,沒有鍵名)
  • 容許儲存任何類型的惟一值,不管是原始值或者是對象引用
  • 能夠遍歷,方法有:adddeletehasclear

WeakSet

  • 成員都是對象
  • 成員都是弱引用,能夠被垃圾回收機制回收,能夠用來保存 DOM 節點,不容易形成內存泄漏
  • 不能遍歷,方法有 adddeletehas

Map

  • 是一種相似於字典的數據結構,本質上是鍵值對的集合
  • 能夠遍歷,能夠跟各類數據格式轉換
  • 操做方法有:setgethasdeleteclear

WeakMap

  • 只接受對象做爲鍵名(null 除外),不接受其餘類型的值做爲鍵名
  • 鍵名是弱引用,鍵值能夠是任意的,鍵名所指向的對象能夠被垃圾回收,此時鍵名是無效的
  • 不能遍歷,方法有 getsethasdelete

推薦文章

搭建一個 vue-cli4+webpack 移動端框架(開箱即用)
從零構建到優化一個相似vue-cli的腳手架
封裝一個toast和dialog組件併發布到npm
從零開始構建一個webpack項目
總結幾個webpack打包優化的方法
總結vue知識體系之高級應用篇
總結vue知識體系之實用技巧
總結vue知識體系之基礎入門篇
總結移動端H5開發經常使用技巧(乾貨滿滿哦!)

關注的個人公衆號不按期分享前端知識,與您一塊兒進步!

相關文章
相關標籤/搜索