JavaScript Map與WeakMap
本文將詳細介紹一下Map與WeakMap物件的具體用法。
上述兩種資料結構是ES2015新增,與已有的物件直接量非常相近。
一.Map物件:
對於物件直接量非常相似,都是鍵值對集合,但是Map物件更為完全,且API豐富。
兩者的核心區別是,物件直接的鍵只能是字串型別或者Symbol型別資料,但是Map鍵可以是各種型別。
可能有些朋友感覺物件直接量的鍵也可以是非字串或者Symbol型別,看如下程式碼例項:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let dataObj = {}; let keyObj = {}; dataObj[keyObj] = "螞蟻部落"; console.log(dataObj[keyObj]);
程式碼執行效果截圖如下:
程式碼簡單分析如下:
(1).建立兩個物件直接量。
(2).將一個物件直接量作為另一個的鍵,然後賦值。
(3).並且可以通過作為鍵的物件訪問對應資料。
(4).上述程式碼上述程式碼並無不妥,貌似上文中的結論出錯了,事實並非如此。
再來看一段程式碼例項:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let dataObj = {}; let keyObj = {}; dataObj[keyObj] = "螞蟻部落"; console.log(dataObj[keyObj]); console.log(dataObj["[object Object]"]);
程式碼執行效果截圖如下:
程式碼分析如下:
(1).雖然在外觀上看,確實是物件作為直接量的鍵。
(2).但是其內部已經將其轉換為字串"[object Object]"。
前面程式碼都是關於非Map物件的內容,現在該輪到本文的主角Map出場了。
下面演示一段關於Map物件的程式碼,首先對齊有一個比較直觀的感受:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let map = new Map(); let objKey = {p: "antzone"}; map.set(objKey, "螞蟻部落") console.log(map.get(objKey)); console.log(map.has(objKey));
程式碼執行效果截圖如下:
程式碼簡單分析如下:
(1).通過建構函式Map建立一個Map物件例項。
(2).然後建立一個物件直接來你個objKey作為map物件的鍵。
(3).通過set方法可以為map物件新增一個成員。
(3).get方法可以獲取對應鍵的值,has方法可以判斷對應的成員是否存在。
可以看到Map物件比物件直接量根據有可操作性,API眾多,上面演示了少數幾個。
Map建構函式的引數可以是陣列,直接看程式碼例項:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let map = new Map([["webName", "螞蟻部落"], ["url", "www.softwhy.com"]]); console.log(map.size); console.log(map.has("webName")); console.log(map.get("webName")); console.log(map.has("url")); console.log(map.get("url"));
程式碼執行效果截圖如下:
程式碼分析如下:
(1).Map建構函式的引數是一個陣列,引數陣列是有特點的。
(2).陣列成員也是陣列,每一個成員陣列具有兩個成員,分別作為map物件的鍵和對應的值。
(3).後面程式碼演示了幾個map物件的屬性和相關方法的功能,非常簡單不多介紹。
Map物件的鍵需要注意的幾個細節:
前文介紹過,Map物件的鍵可以是物件,但是不能認為只要長相一樣,就是相同的鍵。
物件是引用型別,比較的實質是物件的引用,也就是物件所儲存的地址。
程式碼演示如下:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let map = new Map(); map.set({}, "螞蟻部落"); console.log(map.get({}));
程式碼執行效果截圖如下:
可以看到兩個物件雖然長相一模一樣,但是是兩個獨立的物件。
它們的儲存地址不同,所以不能夠列印出字串"螞蟻部落"。
如果鍵是值型別,那麼只要兩者是嚴格相等(===),就可以將它們看做一個鍵。
對於比較特殊的資料NaN,雖然自身與自身都不嚴格相等,但是仍將看做是一個鍵。
[JavaScript] 純文字檢視 複製程式碼執行程式碼let map = new Map(); map.set(NaN, 5); console.log(map.get(NaN)); map.set(-0, 5); console.log(map.get(+0));
程式碼執行效果截圖如下:
上面的執行結果說明了一切,就不再多介紹。
Map物件具有遍歷器介面:
關於遍歷器介面可以參閱JavaScript Iterator遍歷器一章節所以。
毫無疑問Map物件可以使用for of語句和展開運算子,下面通過程式碼簡單演示一下。
[JavaScript] 純文字檢視 複製程式碼執行程式碼let map = new Map([["webName", "螞蟻部落"], ["url", "www.softwhy.com"]]); var arr = [...map]; console.log(arr);
程式碼執行效果截圖如下:
上面演示了展開運算子的對於map物件的操作,非常簡單不多介紹。
關於展開運算子可以參閱JavaScript 展開運算子一章節。
[JavaScript] 純文字檢視 複製程式碼執行程式碼let map = new Map([["webName", "螞蟻部落"], ["url", "www.softwhy.com"]]); for(let elem of map) { console.log(elem); }
程式碼執行效果截圖如下:
上面程式碼演示了for of語句對於Map物件的遍歷操作。
關於for of可以參閱JavaScript for of 語句一章節。
Map物件方法與屬性:
考慮到文章的篇幅問題,Map物件的方法和屬性就不再本文進行介紹。
下面羅列了Map物件的方法和屬性的相關文章連結,需要的朋友可以點選閱讀:
(1).Map.prototype.clear() 方法一章節。
(2).Map.prototype.delete() 方法一章節。
(3).Map.prototype.entries() 方法一章節。
(4).Map.prototype.forEach() 方法一章節。
(5).Map.prototype.get() 方法一章節。
(6).Map.prototype.has() 方法一章節。
(7).Map.prototype.keys() 方法一章節。
(8).Map.prototype.set() 方法一章節。
(9).Map.prototype.values() 方法一章節。
(10).Map.prototype.constructor 屬性一章節。
(11).Map.prototype.size 屬性一章節。
二.WeakMap 物件:
從名稱來看,此物件與Map物件非常相似,它們的不同點在於WeakMap物件的鍵只能是物件。
還有一點需要注意的是,此物件不可以被遍歷,與Map物件相比,不具有size屬性。
並且鍵名所指向的物件,不會計入垃圾回收機制,看如下程式碼例項:
[JavaScript] 純文字檢視 複製程式碼let weakmap = new WeakMap() weakmap.set("num",2)
控制檯截圖如下:
物件的鍵是一個值型別資料,所以報錯了,再強調一下,鍵只能是物件。
物件的鍵是物件的弱引用,所對應的物件可能會被自動回收,當物件被回收後,物件自動移除對應的鍵值對。
程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼let wm = new WeakMap(); let element = document.querySelector(".element"); wm.set(element, "Original"); wm.get(element) // "Original" element.parentNode.removeChild(element); element = null; wm.get(element) // undefined
上述程式碼中,物件的鍵是dom元素節點物件,由於WeakMap物件的鍵是物件的弱引用。
也就是說鍵名所指向的物件並不會被計入垃圾回收機制,所以此物件可能會被自動回收。
當我們刪除對應的dom元素節點之後,element所指向的鍵物件自動消失,所以鍵值對也就被刪除了。
WeakMap物件方法與屬性:
(1).WeakMap.prototype.delete() 方法一章節。
(2).WeakMap.prototype.get() 方法一章節。
(3).WeakMap.prototype.has() 方法一章節。
(4).WeakMap.prototype.set() 方法一章節。
(5).WeakMap.prototype.constructor屬性一章節。
相關文章
- 【ES6基礎】Map與WeakMap
- ES6【Set 、 WeakSet 、Map、WeakMap 】
- ES6 Set,WeakSet,Map,WeakMap
- 深入理解JavaScript中的WeakMap和WeakSetJavaScript
- JavaScript map()JavaScript
- JavaScript map()方法JavaScript
- JavaScript Array map() 方法JavaScript
- javascript 有map嗎JavaScript
- WeakMap delete() 方法delete
- WeakMap get() 方法
- Weakmap詳解
- 引用、淺拷貝及深拷貝 到 Map、Set(含物件assign、freeze方法、WeakMap、WeakSet及陣列map、reduce等等方法)物件陣列
- JavaScript中 Map 物件詳解JavaScript物件
- javascript實現Map結構JavaScript
- forEach與map
- JavaScript 中 forEach、map、filter 詳細JavaScriptFilter
- JavaScript --- Map集合結構詳解JavaScript
- JavaScript — Map集合結構詳解JavaScript
- [Javascript] Object.groupBy & Map.groupByJavaScriptObject
- JavaScript map和reduce的區別JavaScript
- ES6 系列之 WeakMap
- javascript高階函式---filter---map---reduceJavaScript函式Filter
- JavaScript(1)高階函式filter、map、reduceJavaScript函式Filter
- es6-Set與Map
- JavaScript 4/30: 陣列的 map, filter 和 reduce 用法JavaScript陣列Filter
- JavaScript中的new map()和new set()使用詳細(new map()和new set()的區別)JavaScript
- 分散式計算與Map Reduce分散式
- Scala與Java差異(五)之Map與TupleJava
- 在 JavaScript 中,什麼時候使用 Map 或勝過 ObjectJavaScriptObject
- ES6中的Map與Set集合
- Map集合中value()方法與keySet、entrySet區別
- Map
- JavaScript Set與WeakSetJavaScript
- JavaScript與Event LoopJavaScriptOOP
- JavaScript ==原理與分析JavaScript
- 【譯】Object與Map的異同及使用場景Object
- list與Set、Map區別及適用場景
- 【Mark Schmidt課件】機器學習與資料探勘——MLE與MAP機器學習