JS WeakMap 详细用法从基础到实战指南

 更新时间:2026年05月22日 09:11:16   作者:chenlight  
WeakMap是JavaScript中的一个集合类型,类似于普通的Map,但键必须是对象,当键对象不再被引用时,WeakMap会自动将其从集合中删除,有助于垃圾回收机制回收内存,WeakMap中的键是不可以被枚举的,文章总结了WeakMap的核心特法、应用场景和与Map的区别,感兴趣的朋友一起看看吧

WeakMap 是 JavaScript 中的一个集合类型,它类似于普通的 Map,但有几个关键的不同之处:

  • 键的限制‌:WeakMap 的键必须是对象,而不能是原始值(如字符串、数字等)。
  • 内存管理‌:当键对象不再被引用时,WeakMap 会自动将其从集合中删除,这有助于垃圾回收机制回收内存。
  • 不可枚举‌:WeakMap 中的键是不可以被枚举的。

WeakMap 是 ES6 新增的弱引用键值对集合,核心特点:

  • 键必须是对象(不能是原始值:字符串 / 数字 / 布尔等)
  • 键是弱引用:键对象没有其他引用时,会被垃圾回收自动清理(不造成内存泄漏)
  • 不可枚举(没有 keys()/values()/forEach(),也不能用 for...of
  • 只有核心方法set()/get()/has()/delete()

一、基础用法(完整示例)

// 1. 创建 WeakMap
const wm = new WeakMap();
// 2. 定义对象作为键(原始值不能做键)
let user = { name: "张三" };
let info = { age: 20 };
// 3. set(key, value):添加键值对
wm.set(user, "用户信息");
wm.set(info, { id: 1001 });
// 4. get(key):获取值
console.log(wm.get(user)); // 输出:用户信息
// 5. has(key):判断是否存在
console.log(wm.has(info)); // 输出:true
// 6. delete(key):删除键值对
wm.delete(info);
console.log(wm.has(info)); // 输出:false

错误用法(键不能是原始值)

// 报错:Invalid value used as weak map key
wm.set("字符串键", 123); 
wm.set(123, "数值键");

二、核心特性:弱引用(最重要!)

WeakMap 的键是弱引用,如果键对象不再被其他变量引用,垃圾回收机制会自动回收该对象,并从 WeakMap 中移除,不会造成内存泄漏

对比:Map 会造成内存泄漏,WeakMap 不会

// 1. 使用 Map(强引用)
let obj = { id: 1 };
const map = new Map();
map.set(obj, "数据");
obj = null; // 手动释放引用
// Map 中依然保留 obj,不会被回收 → 内存泄漏
// 2. 使用 WeakMap(弱引用)
let obj2 = { id: 2 };
const weakMap = new WeakMap();
weakMap.set(obj2, "数据");
obj2 = null; // 手动释放引用
// 没有其他引用 → 垃圾回收自动清理 obj2 和 weakMap 中的键值对

三、最常用实战场景

场景 1:给 DOM 元素附加数据(无内存泄漏)

操作 DOM 时,用 WeakMap 存储关联数据,DOM 被删除后数据自动回收:

const btn = document.querySelector("#btn");
const domData = new WeakMap();
// 给 DOM 绑定数据
domData.set(btn, { clickCount: 0 });
// 使用数据
btn.addEventListener("click", () => {
  const data = domData.get(btn);
  data.clickCount++;
  console.log(data.clickCount);
});
// DOM 被删除时 → WeakMap 自动清理,无内存泄漏
// btn.remove();

场景 2:私有属性(模拟类的私有数据)

利用 WeakMap 实现真正私有(外部无法访问,不会被遍历):

const _private = new WeakMap();
class User {
  constructor(name) {
    // 私有数据存在 WeakMap 中
    _private.set(this, { name });
  }
  getName() {
    return _private.get(this).name;
  }
}
const u = new User("李四");
console.log(u.getName()); // 李四
console.log(u.name); // undefined(真正私有)

场景 3:缓存对象关联数据

const cache = new WeakMap();
// 缓存计算结果
function getCachedData(obj) {
  if (cache.has(obj)) {
    return cache.get(obj);
  }
  // 模拟耗时计算
  const result = obj.id * 100;
  cache.set(obj, result);
  return result;
}

四、WeakMap 可用方法汇总

方法作用
wm.set(keyObj, value)添加 / 更新键值对
wm.get(keyObj)获取对应值
wm.has(keyObj)判断是否存在,返回布尔值
wm.delete(keyObj)删除指定键值对
wm.clear()已废弃,不要使用

五、WeakMap vs Map(关键区别)

特性WeakMapMap
键类型只能是对象任意类型(对象 / 字符串 / 数字等)
引用类型弱引用(自动垃圾回收)强引用(不会自动回收)
内存泄漏不会可能会
枚举不可枚举(无迭代)可枚举(keys/values/entries)
大小无 size 属性有 size

总结

  • 什么时候用 WeakMap
    • 对象附加额外数据
    • DOM 元素关联数据
    • 类私有属性
    • 不想造成内存泄漏的缓存
  • 记住核心键必须是对象 + 弱引用自动回收 + 不可枚举
  • 它是专门为避免对象关联数据造成内存泄漏设计的 API

到此这篇关于JS WeakMap 详细用法:从基础到实战的文章就介绍到这了,更多相关js weakmap用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一个JavaScript递归实现反转数组字符串的实例

    一个JavaScript递归实现反转数组字符串的实例

    这篇文章主要介绍了一个JavaScript递归实现反转数组字符串的实例,很不错,非常适合新手朋友们
    2014-10-10
  • 前端页面请求接口大规模并发问题的解决办法

    前端页面请求接口大规模并发问题的解决办法

    前端优化大规模并发请求,需合并请求、节流防抖、缓存策略、懒加载及优先级管理,这篇文章主要介绍了前端页面请求接口大规模并发问题的解决办法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-06-06
  • p5.js实现动态图形临摹

    p5.js实现动态图形临摹

    这篇文章主要为大家详细介绍了p5.js实现动态图形临摹,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • js+canvas实现简单扫雷小游戏

    js+canvas实现简单扫雷小游戏

    这篇文章主要为大家详细介绍了js+canvas实现简单扫雷小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • javascript实现鼠标点击生成文字特效

    javascript实现鼠标点击生成文字特效

    这篇文章主要为大家详细介绍了javascript实现鼠标点击生成文字特效,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • 一文搞懂ES6中的Map和Set

    一文搞懂ES6中的Map和Set

    这篇文章主要介绍了ES6中的Map和Set,本文给大家提到了map和object的区别 ,需要的朋友可以参考下
    2019-05-05
  • JS异步任务的并行、串行及二者结合用法

    JS异步任务的并行、串行及二者结合用法

    让多个异步任务按照我们的想法执行,是开发中常见的需求,今天我们就来捋一下,如何让多个异步任务并行,串行,以及并行串行相结合,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • js+html制作简单验证码

    js+html制作简单验证码

    这篇文章主要为大家详细介绍了js结合html制作简单验证码的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • js前端传json后台接收‘‘被转为quot的问题解决

    js前端传json后台接收‘‘被转为quot的问题解决

    这篇文章主要介绍了js前端传json后台接收‘‘被转为"的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • JavaScript实现星星等级评价功能

    JavaScript实现星星等级评价功能

    这篇文章主要为大家详细介绍了JavaScript实现星星等级评价功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03

最新评论