JavaScript Set 和weakset

在ES6, 增加了Set和WeakSet兩個集合,簡單總結一下使用方法以及他們的區別

1.Set是一個新的數據結構,類似於數組,不過裏面的數值是不能重複的

Set 實例的方法分爲兩大類:操作方法(用於操作數據)和遍歷方法(用於遍歷成員)。下面先介紹四個操作方法。

  • add(value):添加某個值,返回 Set 結構本身。
  • delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
  • has(value):返回一個布爾值,表示該值是否爲Set的成員。
  • clear():清除所有成員,沒有返回值

Set 結構的實例有四個遍歷方法,可以用於遍歷成員。

  • keys():返回鍵名的遍歷器
  • values():返回鍵值的遍歷器
  • entries():返回鍵值對的遍歷器
  • forEach():使用回調函數遍歷每個成員

需要特別指出的是,Set的遍歷順序就是插入順序。這個特性有時非常有用,比如使用 Set 保存一個回調函數列表,調用時就能保證按照添加順序調用。

由於Set沒有鍵值,所以keys()和values()返回的結果是一樣的

比如下面的例子,可以看出keys()和values()是一樣的結果,而entries()返回的key和value的值是一樣的。

var 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']
*/

對於foreach,由於Set沒有key, key就是value的值,例如

var set = new Set(['red', 'green'])
set.forEach((key, value)=>{console.log(key + ':' + value)})

/*
red:red
green:green
*/

另外數組的map和filter方法,也可以直接用於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}

通過filter方法,可以很簡單的實現兩個Set的交集,差集,並集等等

2. WeakSet也是一種集合,顧名思義,弱集合(實際上是對集合內數據的弱引用)

它與Set的區別有兩點,一:只能存儲對象,無法存儲基本數據類型,比如數字,Symbol。

二:是一種弱引用,也就是對象加入到WeakSet之後,引用計數不會加一,所以在垃圾回收(根據引用計數進行的判斷)的時候,存儲的對象很可能就沒有了,被回收了,所以遍歷的函數都無法使用。

基於上述兩點,有些方法要注意,例如:

const a = [[1, 2], [3, 4]];
const ws = new WeakSet(a);
// WeakSet {[1, 2], [3, 4]}

放入ws的不是數組a,是a中的內容,那麼如下操作就是錯的

const b = [3, 4];
const ws = new WeakSet(b);
// Uncaught TypeError: Invalid value used in weak set(…)

WeakSet 的一個用處,是儲存 DOM 節點,而不用擔心這些節點從文檔移除時,會引發內存泄漏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章