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
需满足 键是对象 + 需自动内存管理 两大条件。