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
    目录

    Set和WeakSet

    # JavaScript 中 Set 与 WeakSet 的区别、联系及示例


    # 核心区别

    特性 Set WeakSet
    值的类型 允许任意类型的值(对象、原始值) 值必须是对象(非原始值)
    垃圾回收 强引用值 → 阻止垃圾回收 弱引用值 → 不影响垃圾回收
    可遍历性 支持遍历(keys(), values(), for...of) 不可遍历(无遍历方法)
    Size 属性 有 size 属性获取元素数量 无 size 属性
    清除方法 有 clear() 方法 无 clear() 方法
    初始化 可初始化值(new Set([1, 2])) 必须逐项添加(不能初始化)
    性能 适合存储长期存在的数据 内存优化(自动清理无引用值)

    # 核心联系

    1. 集合特性
      二者均为值唯一的集合:add(value) / has(value) / delete(value)
    2. 值唯一性
      集合中每个值都是唯一的(基于严格相等 ===)
    3. 相同方法
      都支持 add(), has(), delete() 方法

    # 代码示例

    # 1. Set 基本用法

    const users = new Set();
    
    // 添加任意类型值
    users.add("Alice");          // ✅ 字符串
    users.add(42);               // ✅ 数字
    users.add({ id: 1 });        // ✅ 对象
    
    console.log(users.size);      // 3
    console.log(users.has(42));   // true
    
    // 遍历Set
    for (const user of users) {
      console.log(user); // "Alice", 42, {id:1}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 2. WeakSet 基本用法

    const userObjects = new WeakSet();
    const alice = { name: "Alice" };
    const bob = { name: "Bob" };
    
    // 只能添加对象引用
    userObjects.add(alice);         // ✅
    userObjects.add(bob);           // ✅
    // userObjects.add("Charlie");  // ❌ TypeError
    
    console.log(userObjects.has(alice));  // true
    
    // 对象销毁后自动清理
    alice = null;  // 移除引用
    
    // 垃圾回收后,WeakSet自动移除alice
    // userObjects.has(alice) → false (无法直接验证)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    # 高级场景示例

    # 场景 1:Set 实现数组去重

    const duplicates = [1, 2, 2, 3, 4, 4];
    const unique = [...new Set(duplicates)]; // [1, 2, 3, 4]
    
    // 对象去重(需注意引用不同)
    const objSet = new Set([{id:1}, {id:1}]);
    console.log(objSet.size); // 2 (不同对象引用)
    
    1
    2
    3
    4
    5
    6

    # 场景 2:WeakSet 检测对象存在性

    const activeSessions = new WeakSet();
    
    function startSession(user) {
      if (activeSessions.has(user)) {
        console.log("Session already exists!");
        return;
      }
      activeSessions.add(user);
      console.log("New session started");
    }
    
    const user = { id: 1001 };
    startSession(user);  // New session started
    startSession(user);  // Session already exists!
    
    // 当用户退出时自动清理
    user = null; 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    # 场景 3:WeakSet 实现私有属性标记

    const protectedFiles = new WeakSet();
    
    class FileSystem {
      constructor(file) {
        protectedFiles.add(file);
        this.file = file;
      }
    
      delete() {
        if (protectedFiles.has(this.file)) {
          throw Error("Protected file cannot be deleted");
        }
        // 删除逻辑...
      }
    }
    
    const secretFile = { name: "config.yml" };
    const fs = new FileSystem(secretFile);
    
    fs.delete(); // ❌ Error: Protected file cannot be deleted
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    # 使用建议

    场景 推荐 原因
    数组去重 Set 高效值唯一性检查
    需要遍历集合元素 Set 支持迭代器接口
    存储原始值 Set WeakSet 不支持原始值
    关联对象的临时状态 WeakSet 自动内存管理,避免泄漏
    标记/验证对象存在性 WeakSet 轻量级且自动清理
    长期存储数据集合 Set WeakSet 无法长期保留值

    核心总结:

    • 使用 Set 处理通用集合操作(遍历、去重、包含原始值)
    • 使用 WeakSet 处理对象关联的临时状态(自动垃圾回收是核心优势)
    编辑 (opens new window)
    上次更新: 2025/08/04, 08:16:58
    Map和WeakMap
    ES5面向对象

    ← Map和WeakMap ES5面向对象→

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