一文详解JS中的Map、Set、WeakMap和WeakSet

作者:闭包旅人时间:2026-10-26 13:49:36浏览:435

本文详细介绍JavaScript中Map、Set、WeakMap和WeakSet四种数据结构。Map用于存储任意类型的键值对,Set用于存储唯一值。WeakMap和WeakSet通过弱引用机制支持垃圾回收,适用于缓存场景。文章包含具体代码示例与使用场景对比,帮助开发者根据需求选择合适的数据结构。

在JavaScript语言中,Map、Set、WeakMap和WeakSet是四种核心的数据结构,各自具备独特的特性与应用场景。

  • Map:Map是一种用于存储键值对的数据结构,其键和值可以是任意数据类型。与传统的对象不同,Map允许使用任意类型的值作为键,而对象仅支持字符串或Symbol类型。此外,Map提供了丰富的操作方法,例如通过size属性获取键值对的数量,以及使用forEach()方法遍历集合。
  • Set:Set是一种用于存储唯一值的集合,其中不包含重复元素,且元素之间没有固定的顺序。与数组不同,Set专注于值的唯一性。它提供了多种实用方法,如add()用于添加新值,delete()用于删除值,has()用于检查值是否存在,以及size属性用于获取集合的大小。
  • WeakMap:WeakMap与Map类似,也是键值对的集合,但其键必须为对象类型,而值可以是任意类型。与Map的关键区别在于,WeakMap的键采用弱引用机制。这意味着如果键对象不再被其他变量引用,它将被垃圾回收器自动回收。这一特性使得WeakMap非常适合用于数据缓存,当对象不再被需要时,相关数据会自动从WeakMap中移除,从而有效释放内存。
  • WeakSet:WeakSet是一种存储唯一值的集合,元素无特定顺序。与Set不同,WeakSet中的值必须是对象,且采用弱引用机制,允许被垃圾回收。WeakSet通常用于存储对象引用,以避免潜在的内存泄漏问题。

以下是Map、Set、WeakMap和WeakSet的具体使用示例:

1. Map:

const myMap = new Map();
const key1 = 'key1';
const key2 = { name: 'John' };
const key3 = function () { console.log('Hello!'); };
myMap.set(key1, 'value1');
myMap.set(key2, 'value2');
myMap.set(key3, 'value3');
console.log(myMap.get(key1)); // 'value1'
console.log(myMap.get(key2)); // 'value2'
console.log(myMap.get(key3)); // 'value3'
console.log(myMap.size); // 3

在示例中,我们创建了一个Map实例,并使用三种不同类型的键(key1、key2、key3)来存储对应的值(value1、value2、value3)。可以通过get()方法获取特定键对应的值,利用size属性查看当前键值对的数量。

2. Set:

const mySet = new Set();
mySet.add('value1');
mySet.add('value2');
mySet.add('value3');
console.log(mySet.has('value1')); // true
console.log(mySet.has('value4')); // false
console.log(mySet.size); // 3
mySet.delete('value2');
console.log(mySet.size); // 2

在此示例中,我们创建了一个Set实例,并通过add()方法向其中添加三个值(value1、value2、value3)。可以使用has()方法检查集合中是否包含特定值,通过size属性获取集合大小,并使用delete()方法删除指定值。

3. WeakMap:

let key1 = { name: 'John' };
let key2 = { name: 'Mary' };
let weakMap = new WeakMap();
weakMap.set(key1, 'value1');
weakMap.set(key2, 'value2');
key1 = null;
console.log(weakMap.get(key1)); // undefined
console.log(weakMap.get(key2)); // 'value2'

示例中创建了一个WeakMap实例,并使用两个对象键(key1、key2)存储对应的值(value1、value2)。随后将key1设置为null,这会导致key1对象被垃圾回收,其关联的值value1也会从WeakMap中自动移除。当尝试使用get()方法访问已被删除的键时,将返回undefined。

4. WeakSet:

let obj1 = { name: 'John' };
let obj2 = { name: 'Mary' };
let weakSet = new WeakSet([obj1, obj2]);
console.log(weakSet.has(obj1)); // true
obj1 = null;
console.log(weakSet.has(obj1)); // false

在示例中,我们创建了一个WeakSet实例,并向其中添加两个对象(obj1、obj2)。可以使用has()方法检查WeakSet中是否存在特定对象。当将obj1设置为null时,该对象及其在WeakSet中的引用会被自动移除。此时使用has()方法尝试访问已被删除的对象,将返回false。

以下是Map、Set、WeakMap和WeakSet之间的主要区别及适用场景分析:

1. Map和Set:

Map和Set均属于集合数据结构,主要区别在于:

  • Map用于存储键值对,支持任意类型作为键;而Set仅存储值,且每个值必须唯一。
  • Map提供了更多操作键值对的方法,如get()、set()和size属性等;Set则提供了更多操作值的方法,如add()、delete()和has()等。

使用场景:

  • 当需要存储键值对并通过键访问值时,推荐使用Map。
  • 当需要存储唯一值时,推荐使用Set。

2. WeakMap和WeakSet:

WeakMap和WeakSet与Map和Set类似,但其键或值采用弱引用机制。当键或值对象没有其他引用时,它们会被垃圾回收,从而不影响程序的内存使用。主要区别在于:

  • WeakMap和WeakSet仅支持使用对象作为键或值。
  • WeakMap和WeakSet不提供size属性,因为其内容可能随时被垃圾回收。

使用场景:

  • 当需要存储可能被垃圾回收的对象,且这些对象仅作为键或值存储时,可以使用WeakMap和WeakSet。
  • 在内存受限的场景下进行缓存时,可以使用WeakMap和WeakSet来存储数据,因为它们会在对象不再被引用时自动释放内存。

本文关于JavaScript中Map、Set、WeakMap和WeakSet的详细介绍到此结束。如需了解更多相关内容,请搜索本站历史文章或继续阅读后续文章。感谢大家的支持!

作者最新文章