Map vs WeakMap in JavaScript

了解了 JavaScript Map,但 WeakMap 又是什麼東西?

前言

前面寫了一篇文章關於 ES6 JavaScript 當中的內建資料結構: Map🔗,這次來談談 WeakMap,它又與 Map 有什麼不同呢?

Map 與 WeakMap 方法比較
WeakMap vs Map 方法比較

會發現 WeakMap 相較 Map 少了非常多可用的方法,這是因為它們的根本處理資料的方式不同,Map 是強引用,而 WeakMap 是弱引用。

WeakMap 的特點

  1. 不阻止鍵被垃圾回收:弱引用的機制使得 WeakMap 在處理需要額外關聯數據但又不想影響原始物件生命週期的場景中非常有用,例如:私有變數🔗替物件(DOM 元素、Class、套件)添加可被自動記憶體回收的額外資訊🔗……
  2. 大致只能使用物件作為 key:作為一個存放弱指標的集合。原始值(如數字、字串)在 JavaScript 中是不可變的,並且不以引用的方式存儲,因此無法對它們應用弱引用的概念。
  3. 不在乎內容及時狀態WeakMap 無法得知 JavaScript 引擎是否已經記憶體清楚了某個項目,因此無法保證 WeakMap 中的所有項目都是有效的,不支援存取所有內容的方式,像是遍歷內容。

總結

let foo = { name: 'foo' };
const map = new Map();
map.set(foo, 'Hello');
foo = undefined;
map.forEach((value, key) => {
console.log(key, value); // { name: 'foo' } 'Hello'
});
// 結論:就算鍵被清除了,map 仍然保留 foo 的引用
// 如果希望隨著 foo 被清除,map 也被清除,可以使用 WeakMap

WeakMap 的設計是為了解決 Map 存在的特定的問題(避免內存洩漏、允許垃圾回收器自動清理不再需要的數據),可以在合適的場景選用合適的資料結構。

延伸閱讀