前言
昨天剛研究完另一種數據結構Symbol
趁記憶猶新的時候,把 Set 跟 Map一起解決!!

在ES6之前,儲存數據的結構主要有兩種:
- Array
- Object
在ES6中新增了另外兩種數據結構: Set、Map
以及它们的另外形式WeakSet、WeakMap
Set
Set是es6新增的數據結構,類似於樹組,
但是裡面的值都是唯一的,沒有重複的值,我們一般稱為集合
Set本身是一个構造函數,用來生成 Set 數據結構
1 | const s = new Set(); |
- 構造函數的三大特點
構造函數的函數名的第一個字母通常大寫。
函數體內使用this關鍵字,代表所要生成的對象實例。
生成對象的時候,必須使用new命令來調用構造函數。
Set 的常見方法
Set常見的屬性:
size:返回Set中元素的個數;
Set常用的方法:add(value):添加某個元素,返回Set對象本身;
delete(value):從set中刪除和這個值相等的元素,返回Boolean類型;
has(value):判斷set中是否存在某個元素,返回Boolean類型;
clear():清空set中所有的元素,沒有返回值;
forEach(callback, [ thisArg]):通過forEach遍歷set;
size
1 | s.size // 0 <-----返回裡面的length |
add(value)
添加某個值,返回 Set 結構本身
當添加已經存在的元素,set不會進行處理添加
1 | s.add(1).add(2).add(2); // 2只被加了一次 |
delete(value)
删除某個值,返回一個布爾值(True or False),表示删除是否成功
1 | s.delete(1) //false |
has(value)
返回一个(True or False),判斷該值是否為Set的元素
1 | s.has(2) //false |
clear()
清除Set內所有元素,沒有返回值
1 | s.clear() |
遍歷
Set實現遍歷的方法有下:
- **keys()**:返回key值的遍歷器
- **values()**:返回value值的遍歷器
- **entries()**:返回entries的遍歷器
- **forEach()**:使用回调函數遍歷每個元素
Set的遍歷順序就是插入順序
1 | let set = new Set(['red', 'green', 'blue']); |
forEach()用於對每個成員執行某種操作,沒有返回值,鍵值、鍵名都相等,
同樣的forEach方法有第二個參數,用於綁定處理函數的this
1 | let set = new Set([1, 4, 9]); |
擴展運算符和Set 結構相結合實現數組或字符串去重
1 | // Array |
實現並集、交集、和差集
1 | let a = new Set([1, 2, 3]); |
Map
Map類型是key值對的有序列表,而key和value都可以是任意類型
Map本身是一個構造函數,用來生成 Map 數據結構
1 | const m = new Map() |
Map的常見方法
Map常見的屬性:
size:返回Map中元素的個數;
Map常用的方法:set(key, value):在Map中添加
key、value,並且返回整個Map對象get(key):根據
key獲取Map中的value;delete(value):從Map中刪除和這個值相等的元素,返回Boolean類型;
has(value):判斷Map中是否存在某個元素,返回Boolean類型;
clear():清空Map中所有的元素,沒有返回值;
forEach(callback, [ thisArg]):通過forEach遍歷Map;
Size
size屬性返回Map 結構的元素總數。
1 | const map = new Map(); |
set()
設置key對應的鍵值為value,然後返回整個Map 結構
如果key已經有值,則value值會被更新,否則就新生成該value
同時返回的是當前Map對象,可採用鍊式寫法
1 | const m = new Map(); |
get()
get方法讀取key對應的value值,如果找不到key,返回undefined
1 | const m = new Map(); |
has()
has方法返回一個Boolean,表示某個key是否在當前Map 對象之中
1 | const m = new Map(); |
delete()
delete方法刪除某個key,返回true。如果刪除失敗,返回false
1 | const m = new Map(); |
clear()
clear方法清除所有元素,沒有返回值
1 | let map = new Map(); |
遍歷
Map結構原生提供三個遍歷器生成函數和一個遍歷方法:
- **keys()**:返回
key的遍歷器 - **values()**:返回
value的遍歷器 - **entries()**:返回
所有元素的遍歷器 - **forEach()**:遍歷Map 的所有
元素
遍歷順序就是插入順序
1 | const map = new Map([ |
複製與合併
clone
1 | var original = new Map([ |
合併
1 | var first = new Map([ |
Map也可以跟 Array 合併:
1 | var first = new Map([ |
WeakSet 和 WeakMap
WeakSet
和Set類似的另外一個數據結構稱之為WeakSet,
也是內部元素不能重複的數據結構。
與Set有何差異
WeakSet中只能存放
引用類型,不能是其他類型的值;引用類型統稱為object 類型,細分的話有:Object類型、Array類型、Date類型、RegExp類型、Function類型
WeakSet對元素的引用是
弱引用,如果沒有其他引用對某個對象進行引用,那麼垃圾回收機制可以對該對象進行回收;
舉個例子
1 |
|
來舉一個實際 Stack Overflow 的案例
不能通過非構造方法創建出來的對象調用構造函數的方法
1 | const personSet = new WeakSet() |
WeakMap
和Map類型的另外一個數據結構稱之為WeakMap,
也是以key值對的形式存在的。
在API中WeakMap與Map有兩個區別
- 沒有遍歷操作的
API - 沒有
clear清空方法
1 | // WeakMap 可以使用 set 方法添加元素 |
WeakMap只接受Obj作為key(null除外),不接受其他類型的值作為key
1 | const map = new WeakMap(); |
WeakMap的key所指向的Obj,一旦不再需要,裡面的key和所對應的value會自動消失,不用手動刪除
舉個例子: 在網頁的DOM 元素上添加數據,就可以使用WeakMap結構,當該DOM 元素被清除,其所對應的WeakMap`記錄就會自動被移除
1 | const wm = new WeakMap(); |
注意:WeakMap弱引用的只是key,而不是value。key依然是正常引用
下面代碼中,key值obj會在WeakMap產生新的引用,當你修改obj不會影響到內部value
1 | const wm = new WeakMap(); |
結論
新增了兩個set&map數據結構,找資料發現還有他們對應的弱型別-.-+
搞得一個頭兩個大!!!
找了很多範例,終於是有一點點點點的明白
希望大家也清楚了^_______________^
