JavaScript Set與WeakSet
本文將通過程式碼例項詳細介紹一下Set與WeakSet資料結構的用法。
兩種資料結構是ES2015新增,與陣列非常相似,但是區別也很明顯,下面會介紹。
一.Set物件:
通過Set()建構函式可以建立一個Set物件例項。
此物件與陣列非常相似,但是Set物件中的元素不能重複,這是與陣列的最重大區別。
利用此特點,我們可以輕鬆實現之前之前需要繁瑣的程式碼實現的功能。
首先看一段程式碼例項:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let set = new Set(); [1, 2, 3, 4, 2, 8, 4].map(function (elem) { set.add(elem); }) for (var elem of set) { console.log(elem) }
程式碼執行效果截圖如下:
對上述程式碼分析如下:
(1).首先通過Set()建構函式建立一個Set物件例項set。
(2).通過map方法迴圈遍歷陣列的中的每一個元素,嘗試將它們逐一新增到set物件中。
(3).最後通過for of迴圈遍歷set物件中的每一個成員,可以發現沒有重複的。
(4).也就是說,set中已經存在的成員,不允許再被新增。
特別強調一點,JavaScript中NaN與它自身不相等,但是在Set物件中也只能存在一個,不再通過程式碼演示。
建構函式Set的引數可以是陣列,陣列的成員可以作為Set物件的成員,具有去重功能。
程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let set = new Set([1, 2, 3, 4, 2, 8, 4]); let arr = [...set]; console.log(arr);
程式碼執行效果截圖如下:
上述程式碼分析如下:
(1).建構函式的引數是一個陣列,陣列元素有重複現象。
(2).由於Set物件不允許有重複元素,所以能夠做到去重功能。
(3).然後再通過展開運算子,將set物件成員寫入陣列中,從而簡單實現了陣列去重功能。
此物件具有遍歷器結構,關於遍歷介面可以參閱JavaScript Iterator 遍歷器一章節。
具有遍歷器介面,也就意味著可以使用展開運算子和for of迴圈,上面程式碼已經涉及,不再演示。
更多內容可以參閱如下兩篇文章:
(1).JavaScript for of迴圈一章節。
(2).JavaScript 展開運算子一章節。
[JavaScript] 純文字檢視 複製程式碼執行程式碼let set = new Set(); set.add({}); set.add({}); console.log(set.size);
程式碼執行效果截圖如下:
上述程式碼分析如下:
(1).前文已經介紹,Set物件中不能有重複元素。
(2).但是上述物件貌似新增了兩個一模一樣的元素,並且新增成功。
(3).事實並非如此,兩個物件雖然外觀一模一樣,是兩個獨立的物件。
(4).物件是引用型別資料,是否相同,需要看它們的儲存地址是否相同。
關於應用型別資料可以參閱JavaScript 值型別和引用型別一章節。
物件屬性與方法:
此物件具有諸多屬性與方法,考慮到篇幅問題,本文不做介紹。
下面是屬性與方法相關文章列表:
(1).Set.prototype.add() 方法一章節。
(2).Set.prototype.clear() 方法一章節。
(3).Set.prototype.delete() 方法一章節。
(4).Set.prototype.entries() 方法一章節。
(5).Set.prototype.forEach() 方法一章節。
(6).Set.prototype.has() 方法一章節。
(7).Set.prototype.values() 方法一章節。
(8).Set.prototype.constructor 屬性一章節。
(9).Set.prototype.size 屬性一章節。
二.WeakSet物件:
從名稱看,此物件與Set物件非常相似,其成員也不能重複。
Set物件的成員可以是任意型別,但是WeakSet物件成員只能是引用型別。
程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼let weakset = new WeakSet(); weakset.add(5)
程式碼執行效果截圖如下:
由於上述程式碼新增的成員非引用型別,所以會報錯。
[JavaScript] 純文字檢視 複製程式碼執行程式碼let weakset = new WeakSet(); weakset.add({}); console.log(weakset.size);
程式碼執行效果截圖如下:
上述程式碼成功為WeakSet物件新增一個引用型別成員。
WeakSet建構函式的引數也可以是陣列,與Set建構函式相同。
但是,陣列的成員必須是引用型別,比如[1,2,3,4]不可以作為WeakSet()建構函式的引數。
但是[[1, 2], [3, 4]]可以作為建構函式的引數,程式碼例項如下:
程式碼執行效果截圖如下:
前面介紹了WeakSet物件的成員必須是引用型別資料,此引用型別資料是弱引用。
也就是垃圾回收機制不會考慮WeakSet物件例項對該成員物件的引用,如果其他物件不再引用此物件成員。
那麼垃圾回收機制就會收回此物件成員所佔用的空間,並不會考慮此物件成員是否當前仍然是WeakSet的成員。
特別說明:與Set物件不同,WeakSet物件不具有size屬性,也不能遍歷。
看一段簡單的程式碼例項:
[JavaScript] 純文字檢視 複製程式碼let weakset = new WeakSet() class Antzone { constructor() { weakset.add(this) } method () { if (!weakset.has(this)) { throw new TypeError("方法只能在Antzone例項上呼叫") } } }
上述程式碼分析如下:
(1).通過weakset物件儲存Antzone類物件例項。
(2).method是Antzone類的例項方法,在呼叫此方法的時候會通過weakset.has方法判斷是否具有this物件例項,如果沒有則說明不是通過Antzone物件例項呼叫,因為方法可以通過apply等改變呼叫物件。由於作為成員的Antzone物件例項是弱引用,所以刪除例項的時候,不用考慮weakset,也不會出現記憶體洩漏。
物件屬性與方法:
(1).WeakSet.prototype.add() 方法一章節。
(1).WeakSet.prototype.delete() 方法一章節。
(1).WeakSet.prototype.has() 方法一章節。
(1).WeakSet.prototype.constructor 屬性一章節。
相關文章
- 【ES6基礎】Set 與 WeakSet
- ES6【Set 、 WeakSet 、Map、WeakMap 】
- ES6 Set,WeakSet,Map,WeakMap
- 深入理解JavaScript中的WeakMap和WeakSetJavaScript
- [Javascript] Perform Set Operations using JavaScript Set MethodsJavaScriptORM
- JavaScript Set物件JavaScript物件
- WeakSet delete() 方法delete
- lombok get/set 與 JavaBean get/setLombokJavaBean
- Vue.set與vue.$set的使用Vue
- JavaScript get set 訪問器屬性JavaScript
- 引用、淺拷貝及深拷貝 到 Map、Set(含物件assign、freeze方法、WeakMap、WeakSet及陣列map、reduce等等方法)物件陣列
- es6-Set與Map
- JavaScript中的new map()和new set()使用詳細(new map()和new set()的區別)JavaScript
- 私有屬性的Get Set 與 Public
- ES6中的Map與Set集合
- Redis中PipeLine使用(二)---批量get與批量setRedis
- set /?
- Set
- list與Set、Map區別及適用場景
- 【譯】Array與Set的異同及使用場景
- C++ 學習筆記(1):STL、Vector 與 SetC++筆記
- SEEDLab —— 環境變數與 Set-UID 實驗變數UI
- JavaScript Map與WeakMapJavaScript
- JavaScript與Event LoopJavaScriptOOP
- JavaScript ==原理與分析JavaScript
- Jet Set
- set -o
- set -e
- 訓練集(train set),驗證集(validation set)和測試集(test set)AI
- 原型鏈上的get與set訪問器屬性原型
- JavaScript原型與原型鏈JavaScript原型
- javascript 與 設計模式JavaScript設計模式
- [JavaScript] Promise 與 Ajax/AxiosJavaScriptPromiseiOS
- javascript非同步與promiseJavaScript非同步Promise
- JavaScript | 函式與方法JavaScript函式
- JavaScript 原型 與 原型鏈JavaScript原型
- javascript——原型與原型鏈JavaScript原型
- JavaScript與ECMAScript 區別JavaScript