前言
昨天剛研究完另一種數據結構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
數據結構,找資料發現還有他們對應的弱型別-.-+
搞得一個頭兩個大!!!
找了很多範例,終於是有一點點點點的明白
希望大家也清楚了^_______________^