淺析Map和WeakMap有什么不同之處、強/弱引用的區別、WeakMap詳解、map的缺點和使用WeakMap的好處


一、Map 和 WeakMap 有什么不同之處

1、Map 是為了解決對象中的 key 只能為字符串的缺陷

//基本的對象
const obj = { 'name': '張飛',, 'age': 18 } // Map
let m = new Map() a.set(obj,1)

  我們的 Map 是可以解決對象的 key 不能為對象的缺陷,但是又隨之而來了一個缺點:耗費內存,強引用

2、什么是 強 / 弱引用

  就是創建引用之后,無法被垃圾資源回收機制進行回收的,就是強引用。強到你設置了null,也分不開

const refence = [ [obj: 1] ]

  現在我們把 obj 賦值為 null,但是我們的 [obj: 1] 是一個數組,也是一個引用的類型,把 obj 賦值為了空,但是 refence 和數組之前還是存在引用的關系,所以無法分開。

  因為我們都知道為了防止內存泄漏,通常把一個對象使用完之后設置為 null,那如果是上面這種情況,就算你設為 null 也無法垃圾回收了。

3、WeakMap 和 Map 的區別

  ES6 考慮到了這一點,推出了:WeakMap 。它對於值的引用都是不計入垃圾回收機制的,所以名字里面才會有一個"Weak",表示這是弱引用(對對象的弱引用是指當該對象應該被GC回收時不會阻止GC的回收行為)。

(1)強/弱引用的區別:Map 強,WeakMap 弱

(2)WeakMap 只接受對象為 key 值

  在實現完美的深拷貝中,我們使用 WeakMap 代替 Map 的使用來解決循環引用的問題,進行優化。

  Map 相對於 WeakMap :

(1)Map 的鍵可以是任意類型,WeakMap 只接受對象作為鍵(null除外),不接受其他類型的值作為鍵

(2)Map 的鍵實際上是跟內存地址綁定的,只要內存地址不一樣,就視為兩個鍵;WeakMap 的鍵是弱引用,鍵所指向的對象可以被垃圾回收,此時鍵是無效的

(3)Map 可以被遍歷, WeakMap 不能被遍歷

  只要外部的引用消失,WeakMap 內部的引用,就會自動被垃圾回收清除。由此可見,有了它的幫助,解決內存泄漏就會簡單很多。

二、WeakMap 詳解

  MDN上說 WeakMap 對象是一組鍵/值對的集合,其中的鍵是弱引用的。其鍵必須是對象,而值可以是任意的。

  注意,WeakMap 弱引用的只是鍵名,而不是鍵值。鍵值依然是正常引用。

  WeakMap 中,每個鍵對自己所引用對象的引用都是弱引用,在沒有其他引用和該鍵引用同一對象,這個對象將會被垃圾回收(相應的key則變成無效的),所以,WeakMap 的 key 是不可枚舉的。

  語法也很簡單:const wp = new WeakMap();

  在使用的過程中我們需要注意 WeakMap 的 key 只能是 Object 類型

// 創建一個在每個實例中存儲私有變量的對象
const internal = obj => { if (!wp.has(obj)) { wp.set(obj, {}); } return wp.get(obj); } class Shape{ constructor(width, height) { internal(this).width = width; internal(this).height = height; } get area() { return internal(this).width * internal(this).height; } } const square = new Shape(10, 10); console.log(square.area);//100
console.log(map.get(square));//根據對象獲得返回值 { height: 100, width: 100 }

  上面代碼示例看到我們通過 internal(this) 然后去設置其屬性。然后可以通過 map.get(square) 獲取到 square 對象。

  WeakMap 好處是在遍歷屬性時或者在執行 JSON.stringify 時不會展示出實例的私有屬性,但它依賴於一個放在類外面的可以訪問和操作的 WeakMap 變量 ,WeakMap 每個鍵對自己所引用對象的引用是 "弱引用",這意味着如果沒有其他引用和該鍵引用同一個對象,這個對象將會被當作垃圾回收,從而得到不確定的結果。

  就是說 WeakMap 里面的數據可能被垃圾回收機制清除或者一個對應在 WeakMap 結構的對象在外部被刪除時,上述情況所對應的WeakMap的鍵值對也會被自動被移除。因此,如果你想要這種類型對象的 key 值的列表,你應該使用 Map。

  常用方法:

(1)WeakMap.prototype.delete(key):移除key的關聯對象。執行后 WeakMap.prototype.has(key)返回false

(2)WeakMap.prototype.get(key):返回key關聯對象,或者 undefined(沒有key關聯對象時)。

(3)WeakMap.prototype.has(key):根據是否有key關聯對象返回一個Boolean值。

(4)WeakMap.prototype.set(key, value)在WeakMap中設置一組key關聯對象,返回這個 WeakMap對象。

(5)WeakMap.prototype.clear() 從WeakMap中移除所有的 key/value 。  (參考 WeakMap)

  除了 WeakMap 還有 WeakSet 都是弱引用,可以被垃圾回收機制回收,可以用來保存DOM節點,不容易造成內存泄漏。

  這里有一篇文章講解的更詳細,可以看看:《你不知道的 WeakMap》—— https://blog.csdn.net/z591102/article/details/106803124/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM