Jinuss's blog Jinuss's blog
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

Web、WebGIS技术博客
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • React

  • Vue

  • JavaScript文章

    • Map和WeakMap
      • Set和WeakSet
      • ES5面向对象
      • ES6面向对象
      • 多种数组去重性能对比
      • 几个高级的JS API
      • JS随机打乱数组
      • 判断是否为移动端浏览器
      • 防抖与节流函数
      • JS获取和修改url参数
      • 比typeof运算符更准确的类型判断
      • Navigator clipboard介绍使用
      • Javascript 语法错题集
      • ESM和CommonJS详解
      • ColorThief的介绍与使用
      • new命令原理
      • 三级目录

    • 学习笔记

    • openlayers

    • threejs

    • MapboxGL

    • 工具

    • 源码合集

    • ECMAScript历年新特性

    • 前端
    • JavaScript文章
    东流
    2025-08-04
    目录

    Map和WeakMap

    # JavaScript 中 Map 与 WeakMap 的区别、联系及示例


    # 核心区别

    特性 Map WeakMap
    键的类型 允许任意类型的键(对象、原始值) 键必须是对象(非原始值)
    垃圾回收 强引用键 → 阻止垃圾回收 弱引用键 → 不影响垃圾回收
    可遍历性 支持遍历(keys(), values(), entries()) 不可遍历(无遍历方法)
    Size 属性 有 size 属性获取键值对数量 无 size 属性
    清除方法 有 clear() 方法 无 clear() 方法
    性能 频繁增删时内存占用较高 内存优化(自动清理无引用键值对)

    # 核心联系

    1. 键值对存储
      二者均为键值对集合:set(key, value) / get(key) / has(key) / delete(key)
    2. 键的唯一性
      键具有唯一性(引用不同的对象视为不同键)

    # 代码示例

    # 1. Map 基本用法

    const user = { id: 1 };
    const settingsMap = new Map();
    
    // 添加任意类型键
    settingsMap.set(user, { theme: "dark" });  // ✅ 对象键
    settingsMap.set("language", "en");         // ✅ 字符串键
    
    console.log(settingsMap.size);           // 2
    console.log(settingsMap.get(user));      // { theme: "dark" }
    
    // 遍历Map
    for (const [key, val] of settingsMap) {
      console.log(`${key}: ${JSON.stringify(val)}`);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 2. WeakMap 基本用法

    const user = { id: 1 };
    const metadata = new WeakMap();
    
    metadata.set(user, { lastLogin: "2023-10-05" });  // ✅ 只允许对象键
    // metadata.set("role", "admin");                 // ❌ TypeError
    
    console.log(metadata.has(user));     // true
    console.log(metadata.get(user));     // { lastLogin: "2023-10-05" }
    
    // 当对象被销毁时
    user = null;  // 移除对user对象的引用
    
    // 垃圾回收后,WeakMap自动删除对应键值对
    // metadata.get(user) → undefined (无法直接验证)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 高级场景示例

    # 场景 1:Map 的强引用问题

    let data = { key: "value" };
    const map = new Map();
    map.set(data, 1);
    
    data = null;  // 移除引用
    
    // Map仍保留键值对 → 内存泄漏
    console.log([...map.keys()]); // [{ key: "value" }] 
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 场景 2:WeakMap 解决内存泄漏

    let data = { key: "value" };
    const weakMap = new WeakMap();
    weakMap.set(data, 1);
    
    data = null;  // 移除唯一引用
    
    // 垃圾回收后,weakMap自动清除键值对
    // 无法直接检查,但内存被释放
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 场景 3:私有属性模拟(WeakMap)

    const privateStore = new WeakMap();
    
    class User {
      constructor(name) {
        // 每个实例关联私有数据
        privateStore.set(this, { name });
      }
      
      getName() {
        return privateStore.get(this).name;
      }
    }
    
    const alice = new User("Alice");
    console.log(alice.getName());  // "Alice" 
    
    // 外部无法访问私有数据
    console.log(alice.name);       // undefined
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    # 使用建议

    场景 推荐 原因
    需要遍历键/值 Map 支持遍历操作
    存储原始值作为键 Map WeakMap 不支持原始值键
    管理对象私有数据 WeakMap 避免内存泄漏,自动清理
    临时关联对象与元数据 WeakMap 对象销毁时自动解除关联
    缓存大量长期数据 Map WeakMap 无大小控制和遍历能力

    核心总结:优先使用 Map 通用场景;选择 WeakMap 需满足 键是对象 + 需自动内存管理 两大条件。

    编辑 (opens new window)
    上次更新: 2025/08/04, 08:16:58
    rollup-plugin-visualizer
    Set和WeakSet

    ← rollup-plugin-visualizer Set和WeakSet→

    最近更新
    01
    Set和WeakSet
    08-04
    02
    ECMAScript2025(ES16)新特性
    07-30
    03
    ECMAScript2024(ES15)新特性
    07-30
    更多文章>
    Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式