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 对象的引用,以便垃圾回收器将其清理。
相关文章
|
3月前
|
索引
ES5常见的数组方法
ES5常见的数组方法
|
4月前
|
JavaScript 前端开发 Java
ES6新特性(六):类
ES6新特性(六):类
|
7月前
|
存储 Java
ES6中的WeakMap和WeakSet:特性和用途2
ES6中的WeakMap和WeakSet:特性和用途2
49 1
|
7月前
|
存储 JavaScript 前端开发
ES6中的WeakMap和WeakSet:特性和用途
在JavaScript的ES6版本中,引入了两种新的数据结构——WeakMap和WeakSet。与Map和Set相比,这两种数据结构有一些特殊的特点和用途,因此在某些场合下,它们是更好的选择。本文将深入探讨WeakMap和WeakSet的特性和用途。
ES6常见的数组方法
ES6常见的数组方法
48 1
每天3分钟,重学ES6-ES12(一)字面量的增强 解构
每天3分钟,重学ES6-ES12(一)字面量的增强 解构
69 0
|
前端开发 JavaScript
【ES6丨前端进阶基础 】ES6的关键字,新特性以及解构赋值
【ES6丨前端进阶基础 】ES6的关键字,新特性以及解构赋值
143 0
【ES6丨前端进阶基础 】ES6的关键字,新特性以及解构赋值