JavaScript中WeakSet和WeakMap的用法详解

 更新时间:2025年09月06日 08:31:07   作者:前端小巷子  
WeakSet和WeakMap是JavaScript中处理对象的特殊数据结构,WeakSet用于存储对象集合,而WeakMap用于存储键值对,这篇文章主要介绍了JavaScript中WeakSet和WeakMap用法的相关资料,需要的朋友可以参考下

前言

在JavaScript中,WeakSetWeakMap 是两个相对较少被提及但非常有用的集合类型。它们与我们熟悉的 MapSet 类似,但有一些独特的特性和用途。

一、从对象和 Map 开始

在深入探讨 WeakSetWeakMap 之前,我们先简单回顾一下 JavaScript 中的对象和 Map

对象

对象是 JavaScript 中最常用的数据结构之一。它是一个键值对的集合,键和值都可以是任意类型。例如:

const algorithm = { site: "leetcode" };
console.log(algorithm.site); // leetcode

for (const key in algorithm) {
  console.log(key, algorithm[key]);
}

// site leetcode
delete algorithm.site;
console.log(algorithm.site); // undefined

对象的属性可以通过点符号(.)访问,也可以通过中括号([])访问。对象的属性可以通过 delete 关键字删除。

Map

Map 是一个更强大的集合类型,它允许键和值为任意类型。与对象不同,Map 的键是唯一的,且 Map 是可迭代的。例如:

const map = new Map();
map.set('name', 'john');
map.set('phone', 'iPhone');
console.log(map.get('phone')); // iPhone
console.log(map.has('phone')); // true
console.log(map.size); // 2

for (const item of map) {
  console.dir(item);
}
// Array(2) ["name", "john"]
// Array(2) ["phone", "iPhone"]

Map 提供了许多有用的方法,如 setgethasdeleteclear

二、WeakMap

WeakMapMap 的一个变种,它与 Map 非常相似,但有一些关键的区别。

特性

  1. 键必须是对象WeakMap 的键必须是对象,不能是原始类型(如字符串、数字等)。例如:

    const John = { name: 'John' };
    const weakMap = new WeakMap();
    weakMap.set(John, 'student');
    // WeakMap {{...} => "student"}
    weakMap.set('john', 'student');
    // Uncaught TypeError: Invalid value used as weak map key
    
  2. 弱引用WeakMap 的键是弱引用的。这意味着如果一个对象只被 WeakMap 引用,而没有其他引用指向它,那么这个对象可能会被垃圾回收器回收。例如:

    let John = { major: "math" };
    const weakMap = new WeakMap();
    weakMap.set(John, 'student');
    John = null; // John 被垃圾回收
    
  3. 不可迭代WeakMap 不支持迭代方法,如 keysvaluesentries。因此,你无法直接遍历 WeakMap 中的键值对。

方法

WeakMap 提供了以下方法:

  • set(key, value):设置键值对。
  • get(key):获取键对应的值。
  • has(key):检查是否存在某个键。
  • delete(key):删除某个键。

使用场景

WeakMap 通常用于以下场景:

  1. 私有数据存储:由于 WeakMap 的键是弱引用的,且不可迭代,它非常适合用于存储私有数据。例如,你可以为一个对象存储一些私有状态,而不用担心这些状态会泄漏到其他地方。

    const privateData = new WeakMap();
    const obj = { public: 'public' };
    privateData.set(obj, 'private');
    console.log(privateData.get(obj)); // private
    
  2. 缓存WeakMap 可以用于缓存对象的某些计算结果。由于键是弱引用的,当对象被垃圾回收时,对应的缓存也会自动清除。

    const cache = new WeakMap();
    const obj = { data: 'some data' };
    cache.set(obj, processData(obj.data));
    

三、WeakSet

WeakSetSet 的一个变种,它也具有一些独特的特性。

特性

  1. 成员必须是对象WeakSet 的成员必须是对象,不能是原始类型。例如:

    const John = { name: 'John' };
    const weakSet = new WeakSet();
    weakSet.add(John);
    // WeakSet {{...}}
    weakSet.add('john');
    // Uncaught TypeError: Invalid value used as weak set key
    
  2. 弱引用WeakSet 中的对象是弱引用的。如果一个对象只被 WeakSet 引用,而没有其他引用指向它,那么这个对象可能会被垃圾回收器回收。例如:

    let John = { major: "math" };
    const weakSet = new WeakSet();
    weakSet.add(John);
    John = null; // John 被垃圾回收
    
  3. 不可迭代WeakSet 不支持迭代方法,如 forEach。因此,你无法直接遍历 WeakSet 中的成员。

方法

WeakSet 提供了以下方法:

  • add(value):添加一个成员。
  • delete(value):删除一个成员。
  • has(value):检查是否包含某个成员。

使用场景

WeakSet 通常用于以下场景:

  1. 对象标记:你可以使用 WeakSet 来标记某些对象,而不用担心这些对象会泄漏。例如,你可以标记某些对象为“已处理”或“已验证”。

    const processed = new WeakSet();
    const obj = { data: 'some data' };
    processed.add(obj);
    console.log(processed.has(obj)); // true
    
  2. 对象池WeakSet 可以用于管理对象池。当对象被垃圾回收时,它们会自动从 WeakSet 中移除,从而避免内存泄漏。

    const objectPool = new WeakSet();
    const obj = { data: 'some data' };
    objectPool.add(obj);
    

四、总结

WeakMapWeakSet 是 JavaScript 中非常有用的集合类型,它们提供了弱引用的特性,这使得它们在某些场景下非常有用。WeakMap 适用于存储私有数据和缓存,而 WeakSet 适用于对象标记和对象池管理。由于它们的弱引用特性,它们可以帮助我们避免内存泄漏,同时保持代码的简洁和高效。

到此这篇关于JavaScript中WeakSet和WeakMap用法的文章就介绍到这了,更多相关JS中WeakSet和WeakMap内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 仅IE支持clearAttributes/mergeAttributes方法使用介绍

    仅IE支持clearAttributes/mergeAttributes方法使用介绍

    仅IE中HTMLElement元素具有clearAttributes/mergeAttributes方法,它们都是非标准的
    2012-05-05
  • js异步编程的演变:回调函数、Promise、‌async/await‌(代码原理演示)

    js异步编程的演变:回调函数、Promise、‌async/await‌(代码原理演示)

    文章讲解了前端js异步编程的演变过程,从‌回调函数到Promise链式调用,再到async/await的出现,强调async/await核心优势:代码像同步写法、错误处理简单、非阻塞主线程,并指出其本质是Generator+自动执行器的封装,同时提醒避免串行await和合理使用try/catch范围
    2025-10-10
  • javascript实现抢购倒计时程序

    javascript实现抢购倒计时程序

    这篇文章主要为大家详细介绍了javascript实现抢购倒计时程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • JS cookie中文乱码解决方法

    JS cookie中文乱码解决方法

    本篇文章主要是对JS中的cookie中文乱码解决方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • JS基于clipBoard.js插件实现剪切、复制、粘贴

    JS基于clipBoard.js插件实现剪切、复制、粘贴

    这篇文章主要介绍了JS实现剪切、复制、粘贴——clipBoard.js 的相关资料,需要的朋友可以参考下
    2016-05-05
  • JavaScript中call()、apply()和bind()方法的用法与区别及适用场景

    JavaScript中call()、apply()和bind()方法的用法与区别及适用场景

    在JavaScript中,call()、apply()和bind()是三个非常重要的函数方法,它们都用于改变函数执行时的this指向,但在使用方式和执行时机上有显著区别,下面给大家介绍JavaScript中call()、apply()和bind()方法的详细用法与区别,感兴趣的朋友一起看看吧
    2025-09-09
  • js中forEach的用法之forEach与for之间的区别

    js中forEach的用法之forEach与for之间的区别

    这篇文章主要介绍了js中forEach的用法之forEach与for之间的区别,forEach() 调用数组的每个元素,并将元素传递给回调函数,下面更多详细介绍需要的小伙伴可以参考一下

    2022-03-03
  • JS数组方法reduce的用法实例分析

    JS数组方法reduce的用法实例分析

    这篇文章主要介绍了JS数组方法reduce的用法,结合实例形式详细分析了JS数组方法reduce的基本功能、使用方法及相关操作注意事项,需要的朋友可以参考下
    2020-03-03
  • bootstrap table表格插件使用详解

    bootstrap table表格插件使用详解

    这篇文章主要为大家详细介绍了bootstrap table表格插件使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • javascript forEach函数实现代码

    javascript forEach函数实现代码

    在Base2中找到一个叫forEach的函数,是我见过的最好的实现。挖出来分析一下。它能对各种普通对象,字符串,数组以及类数组进行遍历。如果原游览器的对象已实现此函数,它则调用原对象的函数。
    2010-01-01

最新评论