WeakSet
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.
WeakSet
是可被垃圾回收的值的集合,包括对象和非全局注册的符号。WeakSet
中的值只能出现一次。它在 WeakSet
的集合中是唯一的。
描述
用例:检测循环引用
递归调用自身的函数需要一种通过跟踪哪些对象已被处理,来应对循环数据结构的方法。
为此,WeakSet
非常适合处理这种情况:
// 对传入的 subject 对象内部存储的所有内容执行回调
function execRecursively(fn, subject, _refs = new WeakSet()) {
// 避免无限递归
if (_refs.has(subject)) {
return;
}
fn(subject);
if (typeof subject === "object") {
_refs.add(subject);
for (const key in subject) {
execRecursively(fn, subject[key], _refs);
}
}
}
const foo = {
foo: "Foo",
bar: {
bar: "Bar",
},
};
foo.bar.baz = foo; // 循环引用!
execRecursively((obj) => console.log(obj), foo);
在此,在第一次运行时创建 WeakSet
,并将其与每个后续函数调用一起传递(使用内部参数 _refs
)。
对象的数量或它们的遍历顺序无关紧要,因此,WeakSet
比 Set
更适合(和执行)跟踪对象引用,尤其是在涉及大量对象时。
构造函数
WeakSet()
-
创建一个新的
WeakSet
对象。
实例属性
这些属性在 WeakSet.prototype
上定义,并且由所有 WeakSet
实例所共享。
WeakSet.prototype.constructor
-
创建了该实例对象的构造函数。对于
WeakSet
实例,初始值是WeakSet
构造函数。 WeakSet.prototype[Symbol.toStringTag]
-
[Symbol.toStringTag]
属性的初始值是字符串"WeakSet"
。该属性被Object.prototype.toString()
所使用。
实例方法
WeakSet.prototype.add()
-
将
value
追加到WeakSet
对象。 WeakSet.prototype.delete()
-
从
WeakSet
中移除value
。此后调用WeakSet.prototype.has(value)
将返回false
。 WeakSet.prototype.has()
-
返回一个表示
value
是否存在于WeakSet
对象中的布尔值。
示例
使用 WeakSet 对象
const ws = new WeakSet();
const foo = {};
const bar = {};
ws.add(foo);
ws.add(bar);
ws.has(foo); // true
ws.has(bar); // true
ws.delete(foo); // 从 set 中删除 foo 对象
ws.has(foo); // false,foo 对象已经被删除了
ws.has(bar); // true,bar 依然存在
注意,foo !== bar
。尽管它们是相似的对象,但是它们不是同一个对象。因此,它们都可以被加入到集合中。
规范
Specification |
---|
ECMAScript Language Specification # sec-weakset-objects |
浏览器兼容性
BCD tables only load in the browser