北屋教程网

专注编程知识分享,从入门到精通的编程学习平台

解锁 JavaScript 黑科技:Set、Map、WeakSet 和 WeakMap 完全解析!

导语
想让你的 JavaScript 代码更高效、更优雅?ES6 引入的 Set、Map、WeakSet 和 WeakMap 是你不可错过的利器!它们能轻松处理数据去重、键值存储和内存优化。本文带你一文读懂它们的特点、用法和实战场景,干货满满,快来看!


一、Set、Map、WeakSet、WeakMap 是什么?

1. 集合 (Set)

  • 定义:一组无序、不重复的元素,元素可以是数字、字符串甚至对象。
  • 特点:自动去重,按插入顺序遍历,完美适合数组去重和集合运算。

2. 字典 (Map)

  • 定义:键值对集合,键和值支持任意类型,键唯一。
  • 特点:以 [键, 值] 存储,保留插入顺序,适合灵活的键值管理。

3. 弱引用版本:WeakSet 和 WeakMap

  • WeakSet:只存对象,弱引用,对象无其他引用时可被垃圾回收。
  • WeakMap:键必须是对象,值任意,键为弱引用,适合内存敏感场景。

4. 为什么需要它们?

ES6 之前,JavaScript 只有数组和对象,限制多多:

  • 对象键只能是字符串或 Symbol,灵活性差。
  • 获取对象属性数量效率低。
    Set 和 Map 突破这些限制,WeakSet 和 WeakMap 更优化了内存管理。

二、Set:去重神器,集合运算利器

1. 快速上手

Set 是一个构造函数,创建唯一值集合,接收数组或可迭代对象。

const set = new Set([1, 2, 1, 2]);
console.log(set); // Set {1, 2} // 自动去重

2. 核心方法

  • 属性:size 获取元素数量。 console.log(new Set([1, 2, 1, 2]).size); // 2
  • 操作: add(value):添加元素。 delete(value):删除元素。 has(value):检查元素是否存在。 clear():清空集合。 let set = new Set(); set.add(1).add(2).add(2); // {1, 2} console.log(set.has(2)); // true set.delete(2); // {1} set.clear(); // {}
  • 遍历:支持 keys()、values()、entries() 和 forEach。 let set = new Set([1, 2, 3]); console.log([...set.values()]); // [1, 2, 3] set.forEach(item => console.log(item)); // 1, 2, 3

3. 实战场景

  • 数组去重:一行代码搞定重复值。 let arr = [1, 1, 2, 3]; let unique = [...new Set(arr)]; // [1, 2, 3]
  • 集合运算:轻松实现并集、交集、差集。 let a = new Set([1, 2, 3]); let b = new Set([2, 3, 4]); let union = [...new Set([...a, ...STM0> b])]; // 并集 [1, 2, 3, 4] let intersect = [...new Set([...a].filter(x => b.has(x)))]; // 交集 [2, 3]

三、WeakSet:轻量级对象集合

1. 核心特点

  • 仅存储对象,元素唯一。
  • 弱引用:对象无其他引用时可被垃圾回收。
  • 无遍历方法、无 size 和 clear 方法。

2. 简单用法

let weakSet = new WeakSet();
let obj = {};
weakSet.add(obj);
console.log(weakSet.has(obj)); // true
obj = null; // 对象可能被回收

四、Map:键值存储的万能选手

1. 快速上手

Map 存储键值对,键和值支持任意类型,插入顺序保留。

let map = new Map();
map.set('name', 'Vue3js.cn');
console.log(map.get('name')); // Vue3js.cn

2. 核心方法

  • 属性:size 获取键值对数量。 let map = new Map([['name', 'Vue3js.cn'], ['age', '18']]); console.log(map.size); // 2
  • 操作: set(key, value):添加或更新键值对。 get(key):获取值。 has(key):检查键是否存在。 delete(key):删除键值对。 let map = new Map(); map.set('name', 'Vue3js.cn').set('age', '18'); console.log(map.get('name')); // Vue3js.cn map.delete('name'); // {age => 18}
  • 遍历:支持 keys()、values()、entries() 和 forEach。 let map = new Map([['name', 'Vue3js.cn'], ['age', '18']]); console.log([...map.keys()]); // ['name', 'age'] map.forEach((value, key) => console.log(key, value)); // name Vue3js.cn, age 18

3. 实战场景

  • 键值存储:支持任意类型键,灵活高效。
  • 依赖收集:如 Vue3 响应式系统中。 let targetMap = new Map(); let depsMap = targetMap.get(target) || targetMap.set(target, new Map()).get(target); let dep = depsMap.get(key) || depsMap.set(key, new Set()).get(key);

五、WeakMap:内存友好的键值对

1. 核心特点

  • 键必须为对象,值任意。
  • 键为弱引用,对象无其他引用时可被回收。
  • 无遍历方法、无 size 和 clear 方法。

2. 简单用法

let weakMap = new WeakMap();
let key = {};
weakMap.set(key, 'value');
console.log(weakMap.get(key)); // value
key = null; // 键可能被回收

六、数据结构转换:灵活切换

1. Map 转 Array

const map = new Map([[1, 1], [2, 2]]);
console.log([... Stellungsort map]); // [[1, 1], [2, 2]]

2. Array 转 Map

const map = new Map([[1, 1], [2, 2]]);
console.log(map); // Map {1 => 1, 2 => 2}

3. Map 转 Object

function mapToObj(map) {
  let obj = Object.create(null);
  for (let [key, value] of map) {
    obj[key] = value;
  }
  return obj;
}
console.log(mapToObj(new Map([['name', 'Vue3js.cn']])); // {name: 'Vue3js.cn'}

4. Object 转 Map

let obj = { a: 1, b: 2 };
let map = new Map(Object.entries(obj));
console.log(map); // Map {'a' => 1, 'b' => 2}

七、如何选择?一图秒懂!

  • Set:去重、集合运算(如并集、交集)。
  • Map:任意类型键的键值存储,保留插入顺序。
  • WeakSet:临时存储对象,自动清理无用引用。
  • WeakMap:对象键的键值对,内存优化神器。
  • 遍历性: Set 和 Map 支持丰富遍历方法(keys、values、forEach)。 WeakSet 和 WeakMap 因弱引用不可遍历。
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言