ES6指的是ECMAScript 6,也被称为ES2015。它是JavaScript的一种版本,是ECMAScript标准的第六个版本,于2015年发布。ECMAScript是JavaScript的规范,定义了语言的核心特性和行为。ES6引入了许多新的语法特性和功能,以使JavaScript代码更加现代化、清晰和强大。 在此专栏中,我们会持续更新有关于ES6的新特性,感兴趣的小伙伴们可以订阅一下~
前言
今天我们来聊聊ES6新特性中的weakset
,WeakSet
(弱引用集合)是 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
注意事项
- 只能包含对象:
WeakSet
只能包含对象作为其元素,而不能包含原始值。
let weakSet = new WeakSet(); // 以下行为是无效的 weakSet.add('Hello'); // TypeError: Invalid value used in weak set
- 不可迭代:
WeakSet
不具备迭代的能力,因此无法使用类似forEach
的方法直接遍历其元素。
Weakset的弱引用特性
WeakSet
使用弱引用的特性,这与传统的引用不同。在 JavaScript 中,引用通常是强引用,即如果一个对象被引用,它将不会被垃圾回收。而使用弱引用的数据结构,例如 WeakSet
,在对象只有弱引用时,不会阻止对象被垃圾回收。
弱引用:
弱引用是指一个对象的引用,不会阻止垃圾回收器回收该对象。如果一个对象只有弱引用,那么当没有其他强引用指向它时,垃圾回收器可能会将其回收。在 WeakSet
中,它存储的是对象的弱引用,这意味着 WeakSet
不会阻止垃圾回收器回收它所包含的对象。
WeakSet
的垃圾回收机制:
- 垃圾回收: 如果在
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去达成我们想要的效果呢?
当我们点击一次按钮后,按钮会被禁用或者消失:
<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 中的一种集合类型,具有以下主要特点:
- 弱引用:
WeakSet
中存储的是对象的弱引用。这意味着,如果在程序中没有其他强引用指向集合中的对象,这些对象可能会被垃圾回收器回收,即使它们存在于WeakSet
中。 - 只能包含对象:
WeakSet
只能包含对象,而不能包含原始值(如字符串、数字等)。 - 不可迭代:
WeakSet
不具备迭代的能力,因此不能使用类似forEach
的方法直接访问其元素。这是为了避免暴露可能已经被垃圾回收的对象。 - 有限的方法:
WeakSet
具有有限的方法,主要包括add(obj)
、has(obj)
和delete(obj)
。没有类似size
属性或forEach
方法这样的集合大小或迭代的功能。 - 不阻止垃圾回收: 与普通对象引用不同,
WeakSet
不会阻止其元素被垃圾回收。当集合中的对象失去其他强引用时,这些对象可能会被垃圾回收器回收。 - 适用于临时存储: 由于
WeakSet
不会阻止对象被垃圾回收,它通常用于需要临时存储对象引用的情况,而不希望影响对象的生命周期。 - 不能清空: 与
Set
不同,WeakSet
没有提供直接清空所有元素的方法。如果需要清空,必须放弃对整个WeakSet
对象的引用,以便垃圾回收器将其清理。