Skip to content

WeakSet

[TOC]

索引

构造方法

  • new WeakSet()(iterable?),用于创建一个 WeakSet 对象的构造函数。暂时没有字面量创建方式

方法

  • weakSet.add()(value),用于向弱集合中添加对象引用
  • weakSet.delete()(value),用于从弱集合中移除特定对象的引用
  • weakSet.has()(value),用于确定特定对象是否存在于弱集合中

WeakSet

构造方法

new WeakSet()@

new WeakSet()(iterable?),用于创建一个 WeakSet 对象的构造函数。暂时没有字面量创建方式

  • iterable?Iterator,可迭代对象,将其元素添加到 WeakSet 中,元素必须是对象(包括数组、函数等)。

  • 返回:

  • weakSetWeakSet,返回一个新的 WeakSet 对象。

核心特性

  1. 仅存储对象:只能添加对象引用(不能存储原始值)

  2. 弱引用机制:如果没有其他引用对某个对象进行引用,那么 GC 可以对该对象进行回收,无法控制何时从 WeakSet 中移除对象。

  3. 不可迭代:没有遍历方法(如 forEach、keys、values)

  4. 无 size 属性:无法获取元素数量

  5. 自动清理:当对象被回收时自动从集合中移除

  6. 唯一性:内部元素不能重复

  7. 不可序列化

    js
    const weakSet = new WeakSet([{ data: "secret" }]);
    console.log(JSON.stringify(weakSet)); // {}

示例

  1. 仅存储对象

    js
    // 有效:存储各种对象类型
    const weakSet = new WeakSet([
      { id: 1 },              // 普通对象
      [1, 2, 3],              // 数组
      function() {},          // 函数
      new Date(),             // Date 实例
      document.body,          // DOM 元素
      new Map()               // 其他集合
    ]);
  2. 不能存储原始值

    js
    // 无效:原始值会抛出 TypeError
    try {
      new WeakSet([1, "text", true]); 
    } catch (e) {
      console.log(e); // TypeError: Invalid value used in weak set
    }
  3. 弱引用行为

    js
    let tempObj = { data: "temporary" };
    const weakSet = new WeakSet([tempObj]);
    
    console.log(weakSet.has(tempObj)); // true
    
    // 解除引用 - 对象可被垃圾回收
    tempObj = null;
    
    // 垃圾回收后,对象自动从 WeakSet 移除
    // 注意:无法直接验证,但引擎会处理
  4. 不可枚举性

    js
    const objA = { a: 1 };
    const objB = { b: 2 };
    const weakSet = new WeakSet([objA, objB]);
    
    // 所有遍历尝试都会失败
    weakSet.forEach(() => {}); // TypeError: weakSet.forEach is not a function
    
    for (const item of weakSet) {} // TypeError: weakSet is not iterable
    
    console.log(weakSet.size); // undefined

方法

add()@

weakSet.add()(value),用于向弱集合中添加对象引用

  • valueobject, 要添加到 WeakSet 的对象(包括数组、函数、日期等对象类型)。

  • 返回:

  • weakSetWeakSet,返回 WeakSet 实例本身,支持链式调用。

核心特性

  1. 同 new WeakSet()

  2. 支持链式调用

    js
    const weakSet = new WeakSet();
    const obj1 = {};
    const obj2 = {};
    
    // 链式调用
    weakSet.add(obj1).add(obj2);

示例

  1. 基本用法

    js
    const weakSet = new WeakSet();
    const elements = new Set();
    
    // 添加DOM元素
    const div = document.createElement('div');
    weakSet.add(div);
    elements.add(div);
    
    // 添加普通对象
    const config = { env: 'production' };
    weakSet.add(config);
    
    // 添加函数
    const handler = () => console.log('Event handled');
    weakSet.add(handler);
  2. 错误处理

    js
    const weakSet = new WeakSet();
    
    // 尝试添加原始值
    try {
      weakSet.add(123);
    } catch (e) {
      console.error('错误:', e.message); 
      // 错误: Invalid value used in weak set
    }
    
    // 尝试添加null
    try {
      weakSet.add(null);
    } catch (e) {
      console.error('错误:', e.message);
    }

delete()

weakSet.delete()(value),用于从弱集合中移除特定对象的引用

  • valueobject,要从 WeakSet 中删除的对象引用(必须是之前添加到集合的对象)。

  • 返回:

  • isDeletedboolean,返回是否移除成功。

核心特性

  1. 对象引用敏感:根据对象的内存引用地址来判断是否是指定的对象。

    js
    const weakSet = new WeakSet();
    const obj = { id: 1 };
    
    // 添加对象
    weakSet.add(obj);
    
    // 删除同一引用
    console.log(weakSet.delete(obj)); // true
    
    // 尝试删除新对象无效(即使内容相同)
    console.log(weakSet.delete({ id: 1 })); // false

示例

  1. 基本用法

    js
    const weakSet = new WeakSet();
    const session = { id: "xyz" };
    const user = { name: "Alice" };
    
    // 添加对象
    weakSet.add(session).add(user);
    
    // 删除对象
    console.log(weakSet.delete(session)); // true
    console.log(weakSet.delete(user));    // true
    
    // 验证删除
    console.log(weakSet.has(session)); // false
    console.log(weakSet.has(user));    // false
  2. 错误处理

    js
    const weakSet = new WeakSet();
    
    // 尝试删除未添加的对象
    console.log(weakSet.delete({})); // false
    
    // 尝试删除原始值
    try {
      weakSet.delete("invalid");
    } catch (e) {
      console.log(e instanceof TypeError); // true
      console.log(e.message); // "Invalid value used in weak set"
    }

has()

weakSet.has()(value),用于确定特定对象是否存在于弱集合中

  • valueobject,要检查是否存在于 WeakSet 中的对象引用。

  • 返回:

  • hasboolean,返回对象是否存在于 WeakSet 中。

核心特性

  1. 对象引用敏感:根据对象的内存引用地址来判断是否是指定的对象。

  2. 垃圾回收时间不确定:检查结果不确定,取决于垃圾回收状态。

    js
    let tempObj = { data: "temporary" };
    weakSet.add(tempObj);
    
    console.log(weakSet.has(tempObj)); // true
    
    // 解除引用
    tempObj = null;
    
    // 垃圾回收后(时间不确定)
    // weakSet.has(原对象) 将返回 false
  3. 无法直接查看内容:无法直接查看 weakSet 内容,只能通过 has() 方法判断元素是否存在。

    js
    const obj = {};
    weakSet.add(obj);
    
    // 无法直接查看内容
    console.log(weakSet); // WeakSet { <items unknown> }

示例

  1. 基本用法

    js
    const weakSet = new WeakSet();
    const session = { id: "xyz" };
    const user = { name: "Alice" };
    
    // 添加对象
    weakSet.add(session).add(user);
    
    // 检查存在性
    console.log(weakSet.has(session)); // true
    console.log(weakSet.has(user));    // true
    
    // 检查未添加对象
    console.log(weakSet.has({}));      // false
  2. 错误处理

    js
    const weakSet = new WeakSet();
    
    // 有效检查
    console.log(weakSet.has({})); // false
    
    // 无效参数类型
    try {
      weakSet.has("invalid");
    } catch (e) {
      console.log(e instanceof TypeError); // true
      console.log(e.message); // "Invalid value used in weak set"
    }