JavaScript中的WeakMap和WeakSet与普通Map/Set有何本质区别?

来源:APP编程网作者:南京网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《JavaScript中的WeakMap和WeakSet与普通Map/Set有何本质区别?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript中的WeakMap和WeakSet与普通Map/Set有何本质区别?》有用,将其分享出去将是对创作者最好的鼓励。

JavaScript提供了四种常用的集合类数据结构,分别是Map、Set、WeakMap和WeakSet,很多开发者容易混淆它们的使用场景,实际上WeakMap、WeakSet和普通Map、Set在核心设计上有本质区别。

JavaScript中的WeakMap和WeakSet与普通Map/Set有何本质区别?

键值类型约束差异

普通Map和Set对存储的键和成员类型没有限制,可以是任意原始类型或者对象类型:

// 普通Map可以存储任意类型的键
const normalMap = new Map();
normalMap.set(1, '数字键');
normalMap.set('str', '字符串键');
normalMap.set(true, '布尔键');
normalMap.set({ a: 1 }, '对象键');

// 普通Set可以存储任意类型的成员
const normalSet = new Set();
normalSet.add(1);
normalSet.add('str');
normalSet.add(true);
normalSet.add({ a: 1 });

而WeakMap的键只能是对象类型,不能是原始类型;WeakSet的成员也只能是对象类型,存储原始类型会直接抛出错误:

// WeakMap键只能是对象
const weakMap = new WeakMap();
weakMap.set({ a: 1 }, '合法');
// weakMap.set(1, '不合法'); // 会抛出TypeError

// WeakSet成员只能是对象
const weakSet = new WeakSet();
weakSet.add({ a: 1 });
// weakSet.add(1); // 会抛出TypeError

引用类型与垃圾回收差异

这是两者最本质的区别。普通Map和Set会对其存储的键、值、成员持有强引用,只要集合本身没有被垃圾回收,其中的内容就不会被回收,哪怕外部已经没有其他引用指向这些内容:

let obj = { name: 'test' };
const normalMap = new Map();
normalMap.set(obj, 'value');
obj = null; // 外部引用置空
// 此时normalMap仍然持有obj的强引用,obj不会被垃圾回收
console.log(normalMap.has({ name: 'test' })); // 此处返回false是因为比较的是引用,不是值相等

而WeakMap和WeakSet对其键、成员仅持有弱引用,当键或成员对象外部没有其他强引用时,即使还在WeakMap或WeakSet中,也会被垃圾回收,且WeakMap/WeakSet会自动移除对应的条目:

let obj = { name: 'test' };
const weakMap = new WeakMap();
weakMap.set(obj, 'value');
obj = null; // 外部引用置空后,obj没有强引用,会被垃圾回收,weakMap中对应条目自动移除
// 由于无法遍历weakMap,无法验证,但该机制是Weak系列结构的核心特性

可遍历性与方法差异

普通Map和Set支持完整的遍历操作,拥有keys()values()entries()forEach()方法,也可以使用for...of遍历,还有size属性可以获取集合长度:

const normalSet = new Set([1, 2, 3]);
console.log(normalSet.size); // 3
for (const item of normalSet) {
    console.log(item); // 依次输出1、2、3
}

WeakMap和WeakSet没有遍历相关的方法和属性,也没有size属性,这是因为弱引用的对象随时可能被回收,遍历的结果是不稳定的,所以语言层面直接禁止了遍历操作:

特性Map/SetWeakMap/WeakSet
键值/成员类型任意类型仅对象类型
引用类型强引用弱引用
可遍历性支持不支持
size属性
清空方法有clear()方法无clear()方法

适用场景差异

普通Map和Set适合需要存储任意类型数据、需要遍历集合、需要知道集合大小的场景,比如存储键值对配置、去重数组等。

WeakMap和WeakSet适合需要临时关联对象数据、不需要遍历、希望避免内存泄漏的场景,比如给DOM元素附加私有数据,当DOM元素被移除时,附加的数据会自动被回收:

// 给DOM元素附加私有数据,避免内存泄漏
const elementData = new WeakMap();
const dom = document.getElementById('test');
elementData.set(dom, { clickCount: 0 });
// 当dom元素从页面移除,没有其他引用时,elementData中对应的条目会自动被回收
注意WeakMap和WeakSet的弱引用仅针对键和成员,值部分仍然是强引用,如果值引用了键对象,还是会形成强引用链,影响垃圾回收。

WeakMapWeakSetMapSetJavaScript修改时间:2026-06-15 07:00:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。