Set和WeakSet数据结构
set
- 成员值唯一
- 添加值的时候,不会进行类型转换,5和'5'不是相同的值,内部判断方法为
Same-value-zero equality,它类似于精确相等运算符(===),且NaN和NaN不相同,视为不同的值,两个空对象也为不同的值 - set结构实例拥有4个遍历的方法(遍历顺序就是插入顺序)
Set.prototype.keys():返回键名的遍历器Set.prototype.values():返回键值的遍历器Set.prototype.entries():返回键值对的遍历器Set.prototype.forEach():使用回调函数遍历每个成员
WeakSet
WeakSet和Set类似,也是不重复的值的集合,有两个区别
- 成员只能是对象,添加其他类型则报错
TypeError: Invalid value used in weak set - 对象成员都是弱引用,即垃圾回收机制不考虑weakSet对该对象的引用,等同于其他对象不再引用该对象,则会被垃圾回收机制回收,不考虑对象还在weakSet中
- 因为垃圾回收机制何时运行不可预测,成员随时可能因为回收而消失,因此 ES6规定
WeakSet 不可遍历
Map和WeakMap数据结构
map
- 键值对形式,键的范围不限于字符串(object也是键值对的形式,但键只限于字符串)
- 注意,只有对同一个对象的引用,Map 结构才将其视为同一个键。(内存引用地址一致)
- 如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,
- 比如
0和-0就是一个键 - 布尔值
true和字符串true则是两个不同的键。 - 另外,
undefined和null也是两个不同的键。 - 虽然
NaN不严格相等于自身,但 Map 将其视为同一个键。
- map结构同样拥有4种遍历方法(遍历顺序就是插入顺序。)
Map.prototype.keys():返回键名的遍历器。Map.prototype.values():返回键值的遍历器。Map.prototype.entries():返回所有成员的遍历器。Map.prototype.forEach():遍历 Map 的所有成员。
WeakMap
WeakMap结构与Map结构类似,也是用于生成键值对的集合。有两个区别
WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。(例如:数值1和Symbol值作为 WeakMap 的键名,都会报错。)WeakMap的键名所指向的对象,不计入垃圾回收机制(弱引用)。 典型应用场景是,在网页的 DOM 元素上添加数据,就可以使用WeakMap结构。当该 DOM 元素被清除,其所对应的WeakMap记录就会自动被移除。
WeakRef
WeakSet 和 WeakMap 是基于弱引用的数据结构,ES2021 更进一步,提供了 WeakRef 对象,用于直接创建对象的弱引用。
let target = {};
let wr = new WeakRef(target);
let obj = wr.deref();//deref方法判断是否被回收
if (obj) { // target 未被垃圾回收机制清除
// ...
}
FinalizationRegistry
ES2021 引入了清理器注册表功能 FinalizationRegistry,用来指定目标对象被垃圾回收机制清除以后,所要执行的回调函数。
const registry = new FinalizationRegistry(heldValue => {
// ....
});
可以通过调用register方法,注册或任何你想要清理回调的对象,传入该对象和所含的值。
registry.register(theObject, "some value");
registry.unregister(theObject);//取消注册