快速掌握WeakMap与Map的区别

135 阅读3分钟

快速掌握WeakMap与Map的区别

在JavaScript中,MapWeakMap是ES6(ECMAScript 2015)中新增的两种非常重要的数据结构,它们都用于存储键值对,但各自有着不同的应用场景和特性。本文将从键的类型、引用方式、遍历能力、以及方法差异等几个方面详细介绍MapWeakMap的区别,帮助前端开发者快速掌握这两种数据结构。

1. 键的类型

Map

  • 任意类型Map的键可以是任意类型的值,包括基本数据类型(如字符串、数字、布尔值)和对象引用。这使得Map非常灵活,能够存储多种类型的键值对。

WeakMap

  • 对象引用WeakMap的键只能是对象引用,不能是基本数据类型的值。这是因为WeakMap的设计初衷是为了存储对象之间的关联,同时不影响这些对象的垃圾回收机制。

2. 引用方式

Map

  • 强引用Map中的键是强引用,即只要Map中的键或值存在,无论键或值是否被其他对象引用,Map对象都会一直保留这个键值对,不会被垃圾回收机制回收。

WeakMap

  • 弱引用WeakMap中的键是弱引用,如果WeakMap的键不再被其他对象引用(即没有其他引用指向这个键对象),那么这个键值对就会被垃圾回收机制自动删除。这种设计有助于防止内存泄漏。
let obj1 = {}
let obj2 = {}

const map1 = new WeakMap()
map1.set(obj1, 1)

const map2 = new Map()
map2.set(obj2, 2)

obj1 = null
obj2 = null

map1.get()
map2.get()

image.png

3. 遍历能力

Map

  • 可遍历Map支持通过forEach()方法或迭代器(如keys(), values(), entries())进行遍历,可以方便地访问和操作所有的键值对。

WeakMap

  • 不可直接遍历WeakMap没有提供直接的遍历方法,也没有迭代器,因此无法直接遍历所有的键值对。这是因为WeakMap的设计初衷是存储临时性的关联,不鼓励开发者遍历其内部元素。

4. 方法差异

共有方法

  • get(key): 根据键获取值。
  • set(key, value): 设置键值对。
  • has(key): 判断键是否存在。
  • delete(key): 删除指定的键值对。

Map特有方法

  • keys(): 返回一个迭代器,按插入顺序包含Map对象中每个元素的键。
  • values(): 返回一个迭代器,按插入顺序包含Map对象中每个元素的值。
  • entries(): 返回一个迭代器,按插入顺序包含Map对象中每个元素的[key, value]数组。
  • forEach(callback, thisArg): 按插入顺序遍历Map对象中的每个键值对,并执行回调函数。
  • size: 返回Map对象中键值对的数量。
  • clear(): 移除Map对象中的所有键值对。

WeakMap特有特性

  • 无size属性:由于WeakMap的键是弱引用,且不支持遍历,因此无法直接获取其内部键值对的数量。
  • 无clear方法:同样因为不支持遍历,WeakMap没有提供清空所有键值对的方法。

5. 应用场景

Map

  • 需要长期保存键值对,且键的类型多样。
  • 需要按插入顺序遍历键值对。

WeakMap

  • 需要存储对象之间的临时关联,且不想影响这些对象的垃圾回收机制。
  • 适用于缓存场景,当对象不再被其他部分引用时,自动从缓存中删除,避免内存泄漏。

结论

MapWeakMap虽然都是用于存储键值对的数据结构,但它们在键的类型、引用方式、遍历能力和方法差异等方面存在显著差异。选择使用哪种数据结构,需要根据具体的应用场景和需求来决定。希望本文能帮助前端开发者快速掌握MapWeakMap的区别,并能在实际项目中灵活运用。