ES6新特性(四):Weakset

ES6指的是ECMAScript 6,也被称为ES2015。它是JavaScript的一种版本,是ECMAScript标准的第六个版本,于2015年发布。ECMAScript是JavaScript的规范,定义了语言的核心特性和行为。ES6引入了许多新的语法特性和功能,以使JavaScript代码更加现代化、清晰和强大。 在此专栏中,我们会持续更新有关于ES6的新特性,感兴趣的小伙伴们可以订阅一下~

前言

今天我们来聊聊ES6新特性中的weaksetWeakSet(弱引用集合)是 JavaScript 中的一种数据结构,用于存储对象的弱引用集合。与常规集合不同,WeakSet仅允许对象作为键,并且不允许使用原始值。WeakSet 中的对象引用是弱引用,这意味着如果没有其他强引用指向某个对象,该对象可能会被垃圾回收器回收,即使它存在于 WeakSet 中。

Weakset

WeakSet 的语法相对简单,它使用 new WeakSet() 构造函数创建一个新的 WeakSet 实例。以下是详细的语法说明:

创建 WeakSet 实例

使用 new WeakSet() 构造函数创建一个新的 WeakSet 实例:

js 复制代码
let weakSet = new WeakSet();

操作方法

WeakSet 提供了几个操作方法,用于向集合中添加、检查或删除元素。

  1. add(value):WeakSet 中添加一个对象。

    js 复制代码
    let obj1 = { key: 'value' };
    let weakSet = new WeakSet();
    weakSet.add(obj1);
  2. delete(value):WeakSet 中删除指定对象。

    js 复制代码
    let obj1 = { key: 'value' };
    let weakSet = new WeakSet();
    weakSet.add(obj1);
    weakSet.delete(obj1);
  3. has(value): 检查 WeakSet 中是否包含指定对象,返回一个布尔值。

    js 复制代码
    let obj1 = { key: 'value' };
    let weakSet = new WeakSet();
    weakSet.add(obj1);
    console.log(weakSet.has(obj1)); // true

注意事项

  1. 只能包含对象: WeakSet 只能包含对象作为其元素,而不能包含原始值。

    js 复制代码
    let weakSet = new WeakSet();
    // 以下行为是无效的
    weakSet.add('Hello'); // TypeError: Invalid value used in weak set
  2. 不可迭代: WeakSet 不具备迭代的能力,因此无法使用类似 forEach 的方法直接遍历其元素。

Weakset的弱引用特性

WeakSet 使用弱引用的特性,这与传统的引用不同。在 JavaScript 中,引用通常是强引用,即如果一个对象被引用,它将不会被垃圾回收。而使用弱引用的数据结构,例如 WeakSet,在对象只有弱引用时,不会阻止对象被垃圾回收。

弱引用:

弱引用是指一个对象的引用,不会阻止垃圾回收器回收该对象。如果一个对象只有弱引用,那么当没有其他强引用指向它时,垃圾回收器可能会将其回收。在 WeakSet 中,它存储的是对象的弱引用,这意味着 WeakSet 不会阻止垃圾回收器回收它所包含的对象。

WeakSet 的垃圾回收机制:

  1. 垃圾回收: 如果在 WeakSet 中唯一引用某个对象的是弱引用,且没有其他强引用指向该对象,垃圾回收器可能会在适当的时机回收该对象。这是因为在 JavaScript 中,垃圾回收器的目标是回收不再被引用的对象。

示例:

js 复制代码
let weakSet = new WeakSet();
let obj = { key: 'value' };

weakSet.add(obj);

console.log(weakSet.has(obj)); // true

obj = null; // 移除对 obj 的强引用

// 此时,垃圾回收器可能会回收 obj,并从 WeakSet 中移除相应的弱引用

console.log(weakSet.has(obj)); // false

在这个例子中,当 obj 被设置为 null 时,强引用被移除,这可能导致 obj 变得不再可达。因为 WeakSet 中的引用是弱引用,垃圾回收器可能会回收 obj,并从 WeakSet 中移除相应的弱引用。这突显了 WeakSet 的一个主要特性,即它不会阻止对象被垃圾回收。

那我们什么时候可以使用Weakset去达成我们想要的效果呢?

当我们点击一次按钮后,按钮会被禁用或者消失:

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="wrap">
    <button id="btn">确认</button>
  </div>

  <script>
    let wrap = document.getElementById('wrap');
    let btn = document.getElementById('btn');

    // 给btn打上标签
    const disabledElements = new WeakSet()
    disabledElements.add(btn)

    btn.addEventListener('click', () => {
      wrap.removeChild(btn)
      console.log(disabledElements); // {}
    })

    
  </script>
</body>
</html>

这是一个简单的 HTML 页面,其中包含一个按钮和一个事件监听器。在点击按钮后,事件监听器会从页面中删除按钮,并使用 WeakSet 来记录已经被禁用的按钮。

让我解释一下代码:

  1. HTML 结构:

    html 复制代码
    <div id="wrap">
      <button id="btn">确认</button>
    </div>

    这是一个包含一个按钮的简单页面。

  2. JavaScript 代码:

    js 复制代码
    let wrap = document.getElementById('wrap');
    let btn = document.getElementById('btn');

    这两行代码获取了页面中的 wrap 元素和 btn 按钮。

    js 复制代码
    const disabledElements = new WeakSet()
    disabledElements.add(btn)

    这里创建了一个 WeakSet,名为 disabledElements,用于存储已被禁用的元素。然后,将按钮 btn 添加到 disabledElements 中,表示该按钮已经被禁用。

    js 复制代码
    btn.addEventListener('click', () => {
      wrap.removeChild(btn)
      console.log(disabledElements); // {}
    })

    这段代码添加了一个点击事件监听器,当按钮被点击时,它会从父元素 wrap 中移除按钮 btn。然后,打印 disabledElements,你会发现在控制台输出一个空的对象 {}。这是因为按钮被移除后,它的引用从 disabledElements 中被移除,WeakSet 不会阻止按钮被垃圾回收,因此 disabledElements 变为空。使用 WeakSet 来追踪已经被禁用的元素,而不会阻止这些元素被垃圾回收。

总结

WeakSet 是 JavaScript 中的一种集合类型,具有以下主要特点:

  1. 弱引用: WeakSet 中存储的是对象的弱引用。这意味着,如果在程序中没有其他强引用指向集合中的对象,这些对象可能会被垃圾回收器回收,即使它们存在于 WeakSet 中。
  2. 只能包含对象: WeakSet 只能包含对象,而不能包含原始值(如字符串、数字等)。
  3. 不可迭代: WeakSet 不具备迭代的能力,因此不能使用类似 forEach 的方法直接访问其元素。这是为了避免暴露可能已经被垃圾回收的对象。
  4. 有限的方法: WeakSet 具有有限的方法,主要包括 add(obj)has(obj)delete(obj)。没有类似 size 属性或 forEach 方法这样的集合大小或迭代的功能。
  5. 不阻止垃圾回收: 与普通对象引用不同,WeakSet 不会阻止其元素被垃圾回收。当集合中的对象失去其他强引用时,这些对象可能会被垃圾回收器回收。
  6. 适用于临时存储: 由于 WeakSet 不会阻止对象被垃圾回收,它通常用于需要临时存储对象引用的情况,而不希望影响对象的生命周期。
  7. 不能清空:Set 不同,WeakSet 没有提供直接清空所有元素的方法。如果需要清空,必须放弃对整个 WeakSet 对象的引用,以便垃圾回收器将其清理。
相关推荐
喜欢踢足球的老罗11 分钟前
搭建一个本地轻量级且好用的学习TypeScript语言的环境
javascript·学习·typescript
豆豆(设计前端)13 分钟前
总结 Vue 请求接口的各种类型及传参方式
前端·javascript·vue.js
BestArsenaI13 分钟前
vue -关于浏览器localstorge数据定期清除的实现
javascript·vue.js·ecmascript
Smile_Gently24 分钟前
Element-plus、Element-ui之Tree 树形控件回显Bug问题。
javascript·vue.js·elementui
一生躺平的仔35 分钟前
# Rust遇上WebAssembly:让JavaScript的计算性能起飞!🚀
前端·javascript
IT 古月方源37 分钟前
跨站脚本攻击(XSS)详解
运维·服务器·前端·网络·tcp/ip·网络安全·xss
你的码,就是我的码41 分钟前
web服务器架构,websocket
服务器·前端·架构
guihong0041 小时前
消息队列:原理、问题与设计全解析
java·面试·rabbitmq
彭友圈1011 小时前
HTML基础入门——简单网页页面
前端·前端框架·html
DogDaoDao2 小时前
leetcode 面试经典 150 题:字母异位词分组
算法·leetcode·面试·vector·哈希表·数据结构与算法·字母异位词分组