ES6新特性(四):Weakset

简介: 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 实例:

let weakSet = new WeakSet();

操作方法

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

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

let obj1 = { key: 'value' };
let weakSet = new WeakSet();
weakSet.add(obj1);

2.delete(value):WeakSet 中删除指定对象。

let obj1 = { key: 'value' };
let weakSet = new WeakSet();
weakSet.add(obj1);
weakSet.delete(obj1);

3.has(value): 检查 WeakSet 中是否包含指定对象,返回一个布尔值。

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

注意事项

  1. 只能包含对象: WeakSet 只能包含对象作为其元素,而不能包含原始值。
let weakSet = new WeakSet();
// 以下行为是无效的
weakSet.add('Hello'); // TypeError: Invalid value used in weak set
  1. 不可迭代: WeakSet 不具备迭代的能力,因此无法使用类似 forEach 的方法直接遍历其元素。

Weakset的弱引用特性

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

弱引用:

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

WeakSet 的垃圾回收机制:

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

示例:

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去达成我们想要的效果呢?

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

<!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 结构:

<div id="wrap">
  <button id="btn">确认</button>
</div>

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

2.JavaScript 代码:

let wrap = document.getElementById('wrap');
let btn = document.getElementById('btn');

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

const disabledElements = new WeakSet()
disabledElements.add(btn)

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

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 对象的引用,以便垃圾回收器将其清理。
相关文章
|
关系型数据库 MySQL 数据安全/隐私保护
Docker实战——MySQL的数据持久化
Docker实战——MySQL的数据持久化
3095 0
Docker实战——MySQL的数据持久化
|
移动开发 JavaScript 前端开发
分享46个JS时间轴特效,总有一款适合您
分享46个JS时间轴特效,总有一款适合您
344 2
|
小程序
【微信小程序】-- 自定义组件 - 纯数据字段 & 组件的生命周期(三十六)
【微信小程序】-- 自定义组件 - 纯数据字段 & 组件的生命周期(三十六)
|
消息中间件 JavaScript Dubbo
spring cloud alibaba 组件版本关系 以及 毕业版本依赖关系
spring cloud alibaba 组件版本关系 以及 毕业版本依赖关系
798 0
|
网络协议
windows_server2012搭建iis并配置http重定向 iis转发
windows_server2012搭建iis并配置http重定向 iis转发
689 1
|
4月前
|
安全 应用服务中间件 网络安全
Nginx SSL/TLS协议栈中配置深度解析与实践指南-优雅草卓伊凡
Nginx SSL/TLS协议栈中配置深度解析与实践指南-优雅草卓伊凡
266 0
Nginx SSL/TLS协议栈中配置深度解析与实践指南-优雅草卓伊凡
|
11月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
358 64
|
12月前
|
前端开发 JavaScript 开发者
Web组件:一种新的前端开发范式
【10月更文挑战第9天】Web组件:一种新的前端开发范式
369 2
|
运维 监控 负载均衡
什么是系统可用性?如何提升可用性?
本文探讨了系统可用性的概念、计算方法及其重要性。可用性指系统能在预定时间内正常运行的比例,计算公式为:(运行时间)/(运行时间+停机时间)。文章列举了不同级别的可用性对应的停机时间,并介绍了提升系统可用性的多种策略,包括冗余设计、故障检测与自动恢复、数据备份与恢复、负载均衡、容错设计、定期维护与更新及使用高可用性云服务和网络优化。这些措施有助于构建更加稳定可靠的系统。
1855 0
|
前端开发 容器
【CSS进阶】使用CSS gradient制作绚丽渐变纹理背景效果(上)
【CSS进阶】使用CSS gradient制作绚丽渐变纹理背景效果
451 1