javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > js Map和WeakMap区别

一文详细说一说Map和WeakMap的区别(面试官常问)

作者:喜欢吃辣椒炒肉拌面

这篇文章主要介绍了Map和WeakMap区别的相关资料,Map和WeakMap都是JavaScript中的键值对数据结构,它们的主要区别在于其键的存储方式和内存管理,需要的朋友可以参考下

一、Map vs WeakMap

特性MapWeakMap
键的类型任意类型(基本类型 / 引用类型)仅支持引用类型(对象)
键的引用特性强引用:键对象不会被 GC 回收弱引用:键对象无其他引用时,会被 GC 自动回收(键值对随之消失)
遍历性支持(keys ()/values ()/entries ()/forEach/for...of)不支持(无遍历方法、无 size 属性)
键的枚举 / 获取可获取所有键(如 Array.from (map.keys ()))无法获取 / 枚举所有键(无 API)
常用 APIset/get/has/delete/clear/sizeset/get/has/delete(无 clear/size)
内存占用键对象未手动删除则一直占用自动回收无引用的键,内存更友好
使用场景需遍历 / 枚举、键为基本类型、长期存储键值对临时关联数据(如 DOM 元素→元数据)、避免内存泄漏

核心差异:弱引用

示例

// Map:强引用导致内存泄漏风险
const map = new Map();
let obj = { id: 1 };
map.set(obj, "data");
obj = null; // 手动置空,但map仍引用obj,GC不会回收

// WeakMap:弱引用自动回收
const weakMap = new WeakMap();
let obj2 = { id: 2 };
weakMap.set(obj2, "data");
obj2 = null; // obj2无其他引用,GC回收后,weakMap中该键值对消失

二、Set vs WeakSet

特性SetWeakSet
值的类型任意类型(基本类型 / 引用类型)仅支持引用类型(对象)
值的引用特性强引用:值对象不会被 GC 回收弱引用:值对象无其他引用时,会被 GC 自动回收(值随之移除)
遍历性支持(keys ()/values ()/entries ()/forEach/for...of)不支持(无遍历方法、无 size 属性)
值的枚举 / 获取可获取所有值(如 Array.from (set))无法获取 / 枚举所有值(无 API)
常用 APIadd/has/delete/clear/sizeadd/has/delete(无 clear/size)
内存占用值对象未手动删除则一直占用自动回收无引用的值,内存更友好
使用场景需遍历 / 枚举、值为基本类型、存储唯一值集合存储临时对象(如 DOM 元素集合)、避免内存泄漏

核心差异:弱引用

示例

// Set:强引用
const set = new Set();
let obj = { id: 1 };
set.add(obj);
obj = null; // set仍引用obj,GC不回收

// WeakSet:弱引用
const weakSet = new WeakSet();
let obj2 = { id: 2 };
weakSet.add(obj2);
obj2 = null; // obj2无其他引用,GC回收后,weakSet中该值消失

三、Map vs Set 区别(补充知识)

Map 和 Set 都是 ES6 新增的有序集合(迭代顺序为插入顺序) ,均为强引用、支持遍历、可存储唯一值,但核心定位和数据结构完全不同,以下是详细对比:

特性MapSet
核心定位键值对集合(键→值映射)值的集合(仅存储唯一值,无键)
存储形式[key, value] 键值对,键唯一、值可重复单个值(value),值必须唯一
重复判定规则键唯一(NaN 视为相同,对象引用不同则视为不同)值唯一(规则同 Map 键的判定)
核心 API(增)set(key, value):按键存值add(value):添加值
核心 API(查)get(key):按键取值;has(key):判断键是否存在has(value):判断值是否存在(无 get
核心 API(删)delete(key):按键删除键值对delete(value):按值删除项
遍历方式可遍历键(keys())、值(values())、键值对(entries()可遍历值(keys()/values() 等价,entries() 返回 [value, value]
长度 / 大小size 属性:返回键值对数量size 属性:返回唯一值数量
使用场景1. 键值映射(如 ID→用户信息)2. 需要通过 “键” 快速查找 “值”3. 存储关联数据1. 存储不重复的唯一值集合(如去重数组)2. 仅需判断 “值是否存在”3. 过滤重复数据

1. Map:键值对存储与查找

const map = new Map();
// 存:键唯一,值可重复
map.set("id1", { name: "张三" });
map.set("id2", { name: "李四" });
map.set("id1", { name: "张三2" }); // 覆盖id1的旧值

// 查:按键取值
console.log(map.get("id1")); // { name: "张三2" }
console.log(map.has("id2")); // true

// 遍历:键、值、键值对
for (const key of map.keys()) console.log(key); // id1、id2
for (const value of map.values()) console.log(value); // {name: "张三2"}、{name: "李四"}
for (const [k, v] of map.entries()) console.log(k, v);

2. Set:唯一值集合(无键)

const set = new Set();
// 存:值唯一,重复添加无效
set.add(1);
set.add(2);
set.add(1); // 无效果,1已存在

// 查:仅能判断值是否存在,无get
console.log(set.has(2)); // true
// console.log(set.get(2)); // 报错:Set 无get方法

// 遍历:keys/values等价,entries返回[值, 值]
for (const val of set.values()) console.log(val); // 1、2
for (const [v1, v2] of set.entries()) console.log(v1, v2); // 1 1、2 2

// 典型场景:数组去重
const arr = [1, 2, 2, 3];
const uniqueArr = [...new Set(arr)]; // [1,2,3]

3.核心总结

维度MapSet
数据结构键值对(字典)单值集合(集合)
核心操作按 “键” 存 / 取 / 删按 “值” 增 / 判 / 删(无取值操作)
重复处理键唯一(值可重复)值唯一(无重复)
核心用途键值映射、关联数据存储去重、唯一值判断

简单记:

三、通用总结

类型核心特点适用场景
Map/Set强引用、支持遍历、键 / 值可存任意类型需持久存储、遍历、键 / 值为基本类型的场景
WeakMap/WeakSet弱引用、不支持遍历、仅存引用类型临时关联数据、避免内存泄漏(如 DOM / 临时对象)

关键提醒

WeakMap/WeakSet 无法遍历 / 获取 size,因为其内部数据会被 GC 动态修改,无法保证数据的稳定性;

而 Map/Set 是 “可预测” 的静态集合(除非手动修改)。

到此这篇关于Map和WeakMap区别的文章就介绍到这了,更多相关js Map和WeakMap区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文