JavaScript 中 Map
與 WeakMap
的區別、聯系及示例
核心區別 特性 Map WeakMap 鍵的類型 允許任意類型的鍵(對象、原始值) 鍵必須是對象 (非原始值)垃圾回收 強引用鍵 → 阻止垃圾回收 弱引用鍵 → 不影響垃圾回收可遍歷性 支持遍歷(keys()
, values()
, entries()
) 不可遍歷 (無遍歷方法)Size 屬性 有 size
屬性獲取鍵值對數量 無 size
屬性 清除方法 有 clear()
方法 無 clear()
方法 性能 頻繁增刪時內存占用較高 內存優化 (自動清理無引用鍵值對)
核心聯系
鍵值對存儲
二者均為鍵值對集合:set(key, value)
/ get(key)
/ has(key)
/ delete(key)
鍵的唯一性
鍵具有唯一性(引用不同的對象視為不同鍵)
代碼示例
1. Map 基本用法
const user = { id: 1 } ;
const settingsMap = new Map ( ) ;
settingsMap. set ( user, { theme: "dark" } ) ;
settingsMap. set ( "language" , "en" ) ; console. log ( settingsMap. size) ;
console. log ( settingsMap. get ( user) ) ;
for ( const [ key, val] of settingsMap) { console. log ( ` ${ key} : ${ JSON . stringify ( val) } ` ) ;
}
2. WeakMap 基本用法
const user = { id: 1 } ;
const metadata = new WeakMap ( ) ; metadata. set ( user, { lastLogin: "2023-10-05" } ) ;
console. log ( metadata. has ( user) ) ;
console. log ( metadata. get ( user) ) ;
user = null ;
高級場景示例
場景 1:Map 的強引用問題
let data = { key: "value" } ;
const map = new Map ( ) ;
map. set ( data, 1 ) ; data = null ;
console. log ( [ ... map. keys ( ) ] ) ;
場景 2:WeakMap 解決內存泄漏
let data = { key: "value" } ;
const weakMap = new WeakMap ( ) ;
weakMap. set ( data, 1 ) ; data = null ;
場景 3:私有屬性模擬(WeakMap)
const privateStore = new WeakMap ( ) ; class User { constructor ( name ) { privateStore. set ( this , { name } ) ; } getName ( ) { return privateStore. get ( this ) . name; }
} const alice = new User ( "Alice" ) ;
console. log ( alice. getName ( ) ) ;
console. log ( alice. name) ;
使用建議 場景 推薦 原因 需要遍歷鍵/值 Map 支持遍歷操作 存儲原始值作為鍵 Map WeakMap 不支持原始值鍵 管理對象私有數據 WeakMap 避免內存泄漏,自動清理 臨時關聯對象與元數據 WeakMap 對象銷毀時自動解除關聯 緩存大量長期數據 Map WeakMap 無大小控制和遍歷能力
核心總結 :優先使用 Map
通用場景;選擇 WeakMap
需滿足 鍵是對象 + 需自動內存管理 兩大條件。