Skip to content

Collections

set

Set 是一种无序且唯一的数据结构,类似于数组,但成员值都是唯一的。

基本用法

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

// 添加元素
set.add(1);
set.add('hello');
set.add([1, 2]); // 引用类型可以重复添加

// 检查元素是否存在
console.log(set.has(1)); // true

// 删除元素
set.delete('hello');

// 获取大小
console.log(set.size); // 2

// 遍历Set
set.forEach((value) => {
  console.log(value);
});

// 清空Set
set.clear();

去重

js
// 数组去重
const arr = [1, 2, 2, 3, 3, 3];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3]

// 字符串去重
const str = 'aabbcc';
const uniqueStr = [...new Set(str)].join('');
console.log(uniqueStr); // 'abc'

交集 并集 补集

js
let a = new Set([1, 2, 3, 4]);
let b = new Set([1, 5, 4, 9]);
//交集
let c = new Set([...a, ...b]);
//并集
let a1 = [...a];
let d = new Set(a1.filter((i) => b.has(i)));
// 补集
let a2 = [...a];
let e = new Set(a2.filter((i) => !b.has(i)));

map

Map 是一种键值对的集合,与普通对象的主要区别在于:

  • 键的类型不限:可以是任意类型(对象、函数、基本类型等)
  • 有序性:按照插入顺序迭代元素
  • 直接获取大小:通过 size 属性
  • 高效的查找与删除

基本用法

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

// 添加键值对
map.set('name', '张三');
map.set(123, '数字键');
map.set({}, '对象键');

// 获取值
console.log(map.get('name')); // 张三

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

// 删除键值对
map.delete('name');

// 获取大小
console.log(map.size); // 2

// 遍历Map
map.forEach((value, key) => {
  console.log(key, value);
});

// 清空Map
map.clear();

深拷贝

js
function deepClone(obj, map = new Map()) {
  // 处理原始值(非对象)
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 处理日期对象
  if (obj instanceof Date) {
    return new Date(obj.getTime());
  }

  // 处理正则表达式
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }

  // 检查循环引用
  if (map.has(obj)) {
    return map.get(obj);
  }

  // 创建新对象/数组
  const clone = Array.isArray(obj) ? [] : {};

  // 记录已处理的对象
  map.set(obj, clone);

  // 递归处理所有属性/元素
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key], map);
    }
  }

  return clone;
}

WeakSet

特性

  • 值必须为对象:只能存储对象引用。
  • 弱引用:对象的引用不会阻止垃圾回收。
  • 不可枚举:无法遍历、获取大小或清空。
  • 主要方法:add(value)、has(value)、delete(value)。
js
const weakSet = new WeakSet();
const obj1 = {};
const obj2 = {};

// 添加对象
weakSet.add(obj1);
weakSet.add(obj2);

// 检查存在性
console.log(weakSet.has(obj1)); // true

// 删除对象
weakSet.delete(obj1);

WeakMap

特性

  • 键必须为对象:原始值(如字符串、数字)不能作为键。
  • 弱引用:键对象的引用不会阻止垃圾回收。
  • 不可枚举:无法遍历、获取大小或清空。
  • 主要方法:set(key, value)、get(key)、has(key)、delete(key)。
js
const weakMap = new WeakMap();
const obj = {};

// 设置键值对
weakMap.set(obj, '秘密数据');

// 获取值
console.log(weakMap.get(obj)); // '秘密数据'

// 检查存在性
console.log(weakMap.has(obj)); // true

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

核心区别

特性Map/SetWeakMap/WeakSet
键/值类型任意类型仅对象(弱引用)
枚举性可遍历(keys()values()不可遍历
大小获取size 属性
垃圾回收影响强引用,阻止回收弱引用,不阻止回收
应用场景常规键值对存储临时关联数据、避免内存泄漏