0

0

javascript weakmap是什么_有什么特殊用途【教程】

狼影

狼影

发布时间:2026-01-19 22:21:08

|

885人浏览过

|

来源于php中文网

原创

WeakMap 是唯一能将数据“悄悄挂载”到对象上且不阻止其被垃圾回收的工具,专治内存泄漏;键必须为对象,因GC只跟踪对象生命周期,原始值会报错。

javascript weakmap是什么_有什么特殊用途【教程】

WeakMap 不是“弱化的 Map”,而是 JavaScript 中唯一能「把数据悄悄挂到对象上,又不拖住它不许销毁」的工具

它解决的不是功能缺失问题,而是内存泄漏这个静默杀手——尤其在长期运行的单页应用、频繁操作 DOM 的场景里,一个没清理的 Map 就可能让成百上千个已移除的节点永远卡在内存里。


WeakMap 的键为什么必须是对象?原始值会报错

因为弱引用只对对象有效。JavaScript 的垃圾回收器(GC)只管理对象的生命周期,对字符串、数字这些原始值根本不“记账”。WeakMap 的设计前提就是:键得是 GC 能识别、能跟踪、能决定是否回收的东西。

所以一旦你写:

立即学习Java免费学习笔记(深入)”;

const wm = new WeakMap();
wm.set('hello', 'world'); // TypeError: Invalid value used as weak map key

就会立刻报错。这不是限制,是强制你思考:这个键是不是真需要被“弱关联”?如果不是对象,那它本就不该进 WeakMap

  • 合法键类型:{}document.getElementById('x')new Date()function() {}[]
  • 非法键类型:'str'42truenullundefined

给 DOM 元素存状态,为什么不用 dataset 或属性?

element.myState = {...} 看似简单,但污染了元素自身属性,可能和未来标准属性冲突;用 dataset 只支持字符串,还得手动序列化反序列化;而用 Symbol 属性虽私有,仍可被 Object.getOwnPropertySymbols() 枚举出来,测试或调试时暴露无遗。

WeakMap 是真正“不可见”的挂载方式:

const elementState = new WeakMap();
<p>const el = document.querySelector('.card');
elementState.set(el, { expanded: true, lastClick: Date.now() });</p><p>// 页面中移除 el 后,只要没其他变量引用它,el 和对应状态自动消失
el.remove(); // 此后 elementState.has(el) → false(即使 el 变量还存在,但对象已无强引用)

关键点:

BiLin AI
BiLin AI

免费的多语言AI搜索引擎

下载
  • 不依赖 DOM 树存在与否,只依赖对象是否还有外部强引用
  • 无法通过 for...inObject.keys()JSON.stringify() 触达,天然防误读
  • 没有 size、不能 clear()、不可遍历——不是缺陷,是防止你把它当通用容器滥用

模拟类私有字段时,WeakMap 和 # 语法有什么区别?

ES2022+ 支持 #privateField 语法,写起来更简洁。但 WeakMap 仍有不可替代的场景:

  • 你需要兼容旧环境(如 IE 或部分 Node.js 版本)
  • 你想把私有数据跨多个类共享(比如基类和子类共用一份元数据)
  • 你传入的对象不是你创建的(比如用户传来的 HTMLElement 或第三方库实例),没法加 # 字段

示例:为任意对象附加仅内部可用的缓存

const _cache = new WeakMap();
<p>class Renderer {
render(obj) {
if (!_cache.has(obj)) {
_cache.set(obj, this.expensiveTransform(obj));
}
return _cache.get(obj);
}
}

这里 obj 可以是任何对象,甚至是你无法修改原型的第三方实例。一旦它被丢弃,缓存条目自动失效,不用 try/catch 或定时清理。


WeakMap 为什么不适合做通用缓存?

因为它不保证键存在——你调用 wm.has(key) 返回 false,未必是没设过,可能是 key 已被 GC 回收了。这导致它无法用于需要稳定命中率的缓存策略(比如 LRU、TTL 控制)。

常见误用:

  • WeakMap 存 API 响应结果,期望多次请求复用——但若请求参数对象是临时创建的(如 { id: 123 }),每次都是新对象,缓存完全失效
  • 依赖 wm.size 监控缓存水位——它根本不存在,连 polyfill 都没法可靠实现
  • 试图用 JSON.stringify() 调试内容——WeakMap 不可序列化,会直接忽略

真正适合它的缓存,只有一种:输入对象本身就有稳定生命周期,且你愿意接受“它一走,缓存就空”的语义。比如缓存某个组件实例的布局计算结果,而不是缓存某次 fetch 的响应。


容易被忽略的一点:value 是强引用的。如果你在 WeakMap 里存了一个大数组或闭包,而 key 对象恰好被回收了,value 本身不会自动释放——除非它也只被这个 value 引用。所以别在 value 里偷偷 hold 住别的长生命周期对象,否则照样泄漏。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

549

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6.1万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号