JavaScript中的Map、Set、WeakMap、WeakSet详解
字数 895 2025-11-04 20:48:20
JavaScript中的Map、Set、WeakMap、WeakSet详解
描述
Map、Set、WeakMap、WeakSet是ES6引入的四种新的数据结构,用于解决特定场景下的数据存储和操作需求。它们与传统的对象和数组相比,在键值类型、性能特性和内存管理方面有着显著差异。
知识点讲解
一、Map(映射)
- 基本概念
- Map是键值对的集合,类似于Object
- 但键可以是任意类型(对象、函数、基本类型),而Object的键只能是字符串或Symbol
- 保持键的插入顺序,遍历时按插入顺序返回
- 创建与基本操作
// 创建Map
const map = new Map()
// 添加键值对
map.set('name', 'John')
map.set(1, 'number one')
map.set({id: 1}, 'object key')
// 获取值
console.log(map.get('name')) // 'John'
// 检查键是否存在
console.log(map.has(1)) // true
// 删除键值对
map.delete('name')
// 获取大小
console.log(map.size) // 2
- 遍历方法
const map = new Map([['a', 1], ['b', 2]])
// 遍历键值对
for (let [key, value] of map) {
console.log(key, value)
}
// 只遍历键
for (let key of map.keys()) {
console.log(key)
}
// 只遍历值
for (let value of map.values()) {
console.log(value)
}
二、Set(集合)
- 基本概念
- Set是值的集合,类似数组
- 但值都是唯一的,不会重复
- 常用于数组去重或值的存在性检查
- 创建与基本操作
// 创建Set
const set = new Set()
// 添加值
set.add(1)
set.add(2)
set.add(2) // 重复值会被忽略
// 检查值是否存在
console.log(set.has(1)) // true
// 删除值
set.delete(1)
// 获取大小
console.log(set.size) // 1
- 数组去重应用
const arr = [1, 2, 2, 3, 4, 4]
const uniqueArr = [...new Set(arr)]
console.log(uniqueArr) // [1, 2, 3, 4]
三、WeakMap(弱映射)
- 特殊特性
- 键必须是对象类型,不能是基本类型
- 键是弱引用,不会阻止垃圾回收
- 不可遍历,没有size属性和遍历方法
- 常用于存储私有数据或元数据
- 使用场景
let obj = {id: 1}
const weakMap = new WeakMap()
// 存储私有数据
weakMap.set(obj, 'private data')
// 当obj被垃圾回收时,对应的键值对会自动删除
obj = null // 下次垃圾回收时weakMap中的对应条目会被清除
四、WeakSet(弱集合)
- 特殊特性
- 值必须是对象类型
- 值是弱引用,不会阻止垃圾回收
- 不可遍历,没有size属性
- 常用于标记对象或检查对象引用是否存在
- 使用场景
const weakSet = new WeakSet()
let obj1 = {id: 1}
let obj2 = {id: 2}
weakSet.add(obj1)
weakSet.add(obj2)
console.log(weakSet.has(obj1)) // true
// 当对象被回收时,自动从WeakSet中移除
obj1 = null
五、四种数据结构的对比总结
| 特性 | Map | Set | WeakMap | WeakSet |
|---|---|---|---|---|
| 键/值类型 | 任意类型 | 任意类型 | 只允许对象 | 只允许对象 |
| 可遍历性 | 是 | 是 | 否 | 否 |
| 弱引用 | 否 | 否 | 是 | 是 |
| 垃圾回收影响 | 无 | 无 | 自动清理 | 自动清理 |
| 主要用途 | 键值对存储 | 值唯一性 | 元数据存储 | 对象标记 |
六、实际应用场景分析
- Map适合场景
- 需要非字符串键的情况
- 需要保持插入顺序的键值对
- 频繁添加删除键值对
- WeakMap适合场景
- 存储对象的私有数据
- 缓存计算结果
- DOM节点关联数据
// DOM节点数据存储示例
const domData = new WeakMap()
const element = document.getElementById('myElement')
// 存储与DOM节点相关的数据
domData.set(element, {clickCount: 0})
// 当DOM节点被移除时,相关数据自动回收
理解这些数据结构的特性和适用场景,有助于在开发中选择最合适的工具来解决具体问题。