前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库WeakMap 键对象 垃圾回收影响
JSJavaScript数组与集合

WeakMap 的键只能是对象吗,它怎样影响垃圾回收?

WeakMap 的价值是让附加数据跟随键的生命周期,而不是提供一个可以精确观察回收时刻的缓存列表。

前端进阶之旅 · 一题精讲更新于 2026.09.06
JavaScript#数组与集合#缓存
先看核心答案读代码示例
理解线索

沿引用关系判断存活

  1. 业务对象由真正使用者持有强引用
  2. 附加元数据WeakMap 按对象身份关联数据
  3. 外部引用仍需排查闭包、列表和全局缓存的持有

非注册 Symbol 支持在旧引擎中可能不同,兼容旧环境时应核对目标支持;不要把主方法可用等同于所有新增键类型都可用。

核心回答

先记住这个答案

现代 WeakMap 的键可以是对象或非注册 Symbol,不能简单说只能用对象;Symbol.for 创建的注册 Symbol,以及字符串、数字等不能作为键。它不会仅因保存键就让键保持强可达,适合给对象附加只在对象存活期间有意义的元数据。键按身份查找,没有 keys、entries 或 size 等枚举能力,也不能据此观察垃圾回收时机。如果其他数组、闭包或全局变量仍强引用对象,它仍可能存活。WeakMap 不替代显式取消订阅、关闭连接或有容量上限的缓存策略。

  • 现代键范围包括对象和非注册 Symbol
  • 弱键不会单独阻止回收,但其他强引用仍有效
  • 不可枚举,也不承诺确定回收时间

对象身份与键类型需要分别验证

示例先给一个任务对象写入元数据,再用结构相同的新对象查询,结果不会命中。随后使用非注册 Symbol 和注册 Symbol 对照现代键规则,错误名称比依赖某一引擎的具体错误文案更稳定。

这些测试只验证可观察的键操作,不尝试断言某个对象几毫秒后被回收。回收受引擎和运行状态影响,用定时器等待后期待条目消失不是可靠的功能测试。

元数据关联与 Symbol 键边界JavaScript
const metadata = new WeakMap();
const task = { id: 1 };
metadata.set(task, { checked: true });
console.log(metadata.get(task).checked);
console.log(metadata.has({ id: 1 }));
const token = Symbol('local');
metadata.set(token, 'allowed');
console.log(metadata.get(token));
try { metadata.set(Symbol.for('shared'), 'invalid'); }
catch (error) { console.log(error.name); }
查看输出与解释
true
false
allowed
TypeError

对象查找按身份,内容相同的新对象不会命中。非注册 Symbol 可以作为现代弱键,注册 Symbol 被拒绝;示例的确定输出不包含任何垃圾回收时机判断。

缓存适用性取决于是否只需按已知对象查询

例如为语法树节点缓存一次分析结果,调用方已经持有节点,只需要按节点取元数据,不需要列出所有历史节点,WeakMap 就能避免缓存表本身额外延长节点生命。

如果产品需要展示全部缓存条目、按最近使用淘汰或限制最大数量,WeakMap 的不可枚举会成为限制。应选择有明确容量与删除策略的 Map 等结构,不能因为名字带 Weak 就认为它自动实现了理想缓存。

弱关联不等于外部资源会自动释放

元数据如果包含关闭函数、订阅或网络资源,垃圾回收不会自动按业务顺序调用它们。组件卸载或任务结束时仍应显式取消,WeakMap 只改变对象可达关系,不能承担确定性的资源协议。

还要检查值是否被其他地方强引用,并经由它再次引用键。WeakMap 内部值回指键并不单独让这对关联永久存活,但外部强引用链可能改变结果,分析必须从实际根引用出发。

回答前,多想一步

容易答错的地方

继续背 WeakMap 只能放对象键
现代规范还允许非注册 Symbol,旧结论忽略了能力演进。回答应区分键类型规则与目标环境支持,并明确注册 Symbol 不在允许范围,避免把所有 Symbol 混为一类。
把对象设为 null 后立即证明内存已释放
这只移除一个变量的引用,其他持有者可能仍存在,回收时刻也不确定。应通过引用关系与合适内存诊断定位问题,而不是用一次赋值和短等待断言垃圾回收结果。
试着用自己的话回答

面试官还会怎么问?

WeakMap 为什么没有 size?

如果能精确枚举或计数存活键,就会把垃圾回收状态变成可直接观察的业务结果。WeakMap 主要支持持有已知键时的查询;需要完整列表应选择显式管理的强集合。

value 可以是字符串或数字吗?

可以,限制主要针对键,值可以是任意 JavaScript 值。是否适合存放大对象仍取决于键生命周期和其他强引用,不能因为键弱引用就忽略值的体积与共享关系。

键对象自身字段改变会影响查询吗?

不会自动改变身份,仍用同一个引用就能查询元数据。若业务希望按字段内容合并不同对象,需要另外设计稳定键和更新规则,WeakMap 不是结构相等字典。

从一道题,走向一组知识

把知识连起来

数组与集合

WeakSet 适合标记对象已处理吗,和 Set 有什么不同?

只需要记录对象是否处理过时比较 WeakSet 的成员语义。

数组与集合

Map.size 与 Object.keys().length 统计的到底是什么?

需要明确计数和枚举时选择强集合并定义范围。

参考资料

  • MDN:WeakMap

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 对象身份与键类型需要分别验证
  3. 缓存适用性取决于是否只需按已知对象查询
  4. 弱关联不等于外部资源会自动释放
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑