JavaScript中的Map、Set、WeakMap、WeakSet详解
字数 847 2025-11-12 15:53:41

JavaScript中的Map、Set、WeakMap、WeakSet详解

在JavaScript中,Map、Set、WeakMap和WeakSet是ES6引入的四种新的集合类型,用于存储和操作数据集合。它们提供了比传统对象和数组更强大的功能,特别是在处理键值对和唯一值方面。

1. Map(映射)
Map是一种键值对集合,其中键可以是任意类型(包括对象、函数等),而普通对象的键只能是字符串或Symbol。

创建与基本操作:

// 创建Map
const map = new Map();

// 添加键值对 - 使用set()方法
map.set('name', 'John');
map.set(1, '数字键');
map.set({id: 1}, '对象键');

// 获取值 - 使用get()方法
console.log(map.get('name')); // 'John'

// 检查键是否存在 - 使用has()方法
console.log(map.has(1)); // true

// 删除键值对 - 使用delete()方法
map.delete('name');

// 获取大小 - 使用size属性
console.log(map.size); // 2

// 清空Map - 使用clear()方法
map.clear();

Map的迭代方法:

const map = new Map([
  ['a', 1],
  ['b', 2],
  ['c', 3]
]);

// 使用keys()获取所有键
for (let key of map.keys()) {
  console.log(key); // 'a', 'b', 'c'
}

// 使用values()获取所有值
for (let value of map.values()) {
  console.log(value); // 1, 2, 3
}

// 使用entries()获取所有键值对(默认迭代器)
for (let [key, value] of map) {
  console.log(key, value);
}

// 使用forEach方法
map.forEach((value, key) => {
  console.log(key, value);
});

2. Set(集合)
Set是一种值的集合,其中每个值都是唯一的(不会重复),值的类型可以是任意的。

创建与基本操作:

// 创建Set
const set = new Set();

// 添加值 - 使用add()方法
set.add(1);
set.add(2);
set.add(2); // 重复值不会被添加
set.add('hello');
set.add({name: 'John'});

// 检查值是否存在 - 使用has()方法
console.log(set.has(1)); // true

// 删除值 - 使用delete()方法
set.delete(2);

// 获取大小 - 使用size属性
console.log(set.size); // 3

// 清空Set - 使用clear()方法
set.clear();

Set的实用场景:

// 数组去重
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]

// 字符串去重
const str = 'hello world';
const uniqueChars = [...new Set(str)].join('');
console.log(uniqueChars); // 'helo wrd'

3. WeakMap(弱映射)
WeakMap与Map类似,也是键值对集合,但有重要区别:

  • 键必须是对象类型(不能是原始值)
  • 键是弱引用,不会阻止垃圾回收
  • 不可迭代,没有size属性和清空方法

WeakMap的使用:

const weakMap = new WeakMap();

let obj1 = {name: 'John'};
let obj2 = {name: 'Jane'};

// 设置键值对
weakMap.set(obj1, '私有数据1');
weakMap.set(obj2, '私有数据2');

// 获取值
console.log(weakMap.get(obj1)); // '私有数据1'

// 检查键是否存在
console.log(weakMap.has(obj1)); // true

// 删除键值对
weakMap.delete(obj1);

// 当obj2不再被引用时,对应的键值对会被自动垃圾回收
obj2 = null;

4. WeakSet(弱集合)
WeakSet与Set类似,但:

  • 值必须是对象类型
  • 值是弱引用,不会阻止垃圾回收
  • 不可迭代,没有size属性

WeakSet的使用:

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.delete(obj1);

// 当obj2不再被引用时,会自动从集合中移除
obj2 = null;

5. 四种集合的对比总结

特性 Map Set WeakMap WeakSet
键/值类型 任意类型 任意类型 对象类型 对象类型
可迭代
有size属性
垃圾回收 强引用 强引用 弱引用 弱引用
使用场景 需要任意类型键的映射 需要唯一值的集合 对象关联的元数据 对象存在的标记

6. 实际应用场景

Map的典型应用:

// 缓存计算结果
const cache = new Map();

function expensiveOperation(key) {
  if (cache.has(key)) {
    return cache.get(key);
  }
  
  const result = /* 复杂计算 */;
  cache.set(key, result);
  return result;
}

// DOM节点关联数据
const domData = new Map();
const button = document.querySelector('button');
domData.set(button, {clickCount: 0});

button.addEventListener('click', () => {
  const data = domData.get(button);
  data.clickCount++;
});

WeakMap的典型应用:

// 私有属性实现
const privateData = new WeakMap();

class Person {
  constructor(name) {
    privateData.set(this, {name});
  }
  
  getName() {
    return privateData.get(this).name;
  }
}

// DOM节点监听器管理
const listenerMap = new WeakMap();

function addListener(element, event, handler) {
  if (!listenerMap.has(element)) {
    listenerMap.set(element, new Map());
  }
  listenerMap.get(element).set(event, handler);
  element.addEventListener(event, handler);
}

理解这些集合类型的特性和适用场景,可以帮助你在实际开发中选择最合适的数据结构,写出更高效、更安全的代码。

JavaScript中的Map、Set、WeakMap、WeakSet详解 在JavaScript中,Map、Set、WeakMap和WeakSet是ES6引入的四种新的集合类型,用于存储和操作数据集合。它们提供了比传统对象和数组更强大的功能,特别是在处理键值对和唯一值方面。 1. Map(映射) Map是一种键值对集合,其中键可以是任意类型(包括对象、函数等),而普通对象的键只能是字符串或Symbol。 创建与基本操作: Map的迭代方法: 2. Set(集合) Set是一种值的集合,其中每个值都是唯一的(不会重复),值的类型可以是任意的。 创建与基本操作: Set的实用场景: 3. WeakMap(弱映射) WeakMap与Map类似,也是键值对集合,但有重要区别: 键必须是对象类型(不能是原始值) 键是弱引用,不会阻止垃圾回收 不可迭代,没有size属性和清空方法 WeakMap的使用: 4. WeakSet(弱集合) WeakSet与Set类似,但: 值必须是对象类型 值是弱引用,不会阻止垃圾回收 不可迭代,没有size属性 WeakSet的使用: 5. 四种集合的对比总结 | 特性 | Map | Set | WeakMap | WeakSet | |------|-----|-----|---------|---------| | 键/值类型 | 任意类型 | 任意类型 | 对象类型 | 对象类型 | | 可迭代 | 是 | 是 | 否 | 否 | | 有size属性 | 是 | 是 | 否 | 否 | | 垃圾回收 | 强引用 | 强引用 | 弱引用 | 弱引用 | | 使用场景 | 需要任意类型键的映射 | 需要唯一值的集合 | 对象关联的元数据 | 对象存在的标记 | 6. 实际应用场景 Map的典型应用: WeakMap的典型应用: 理解这些集合类型的特性和适用场景,可以帮助你在实际开发中选择最合适的数据结构,写出更高效、更安全的代码。