WeakSet
Baseline 廣泛可用 *
WeakSet 是一種可垃圾回收的值的集合,包括物件和未註冊的 Symbol。WeakSet 中的值只能出現一次。在 WeakSet 的集合中是唯一的。
描述
WeakSet 的值必須是可垃圾回收的。大多數原始資料型別可以任意建立且沒有生命週期,因此不能儲存。物件和未註冊的 Symbol 可以儲存,因為它們是可垃圾回收的。
與Set 物件的主要區別在於
-
WeakSet僅包含物件和 Symbol。它們不能包含任意型別的值,而Set可以。 -
WeakSet是弱的,這意味著對WeakSet中物件的引用是弱引用。如果WeakSet中儲存的值沒有其他引用存在,這些值就可以被垃圾回收。注意:這也意味著集合中沒有儲存當前值的列表。
WeakSet是不可列舉的。
鍵的相等性
與常規 Set 一樣,值相等性基於SameValueZero 演算法,該演算法與 === 運算子相同,因為 WeakSet 只能包含物件和 Symbol 值。這意味著對於物件值,相等性基於物件標識。它們是透過引用而不是值進行比較的。
建構函式
WeakSet()-
建立一個新的
WeakSet物件。
例項屬性
這些屬性定義在 WeakSet.prototype 上,並由所有 WeakSet 例項共享。
WeakSet.prototype.constructor-
建立例項物件的建構函式。對於
WeakSet例項,初始值為WeakSet建構函式。 WeakSet.prototype[Symbol.toStringTag]-
[Symbol.toStringTag]屬性的初始值為字串"WeakSet"。此屬性用於Object.prototype.toString()。
例項方法
WeakSet.prototype.add()-
將指定值插入此集合,如果尚不存在。
WeakSet.prototype.delete()-
如果指定值存在於此集合中,則將其從集合中移除。
WeakSet.prototype.has()-
返回一個布林值,指示指定值是否存在於此
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); // removes foo from the set
ws.has(foo); // false, foo has been removed
ws.has(bar); // true, bar is retained
請注意,foo !== bar。雖然它們是相似的物件,但它們不是同一個物件。因此它們都被新增到了集合中。
檢測迴圈引用
遞迴呼叫的函式需要一種方法來防止迴圈資料結構,透過跟蹤哪些物件已經被處理。
WeakSet 非常適合此目的
// Execute a callback on everything stored inside an object
function execRecursively(fn, subject, _refs = new WeakSet()) {
// Avoid infinite recursion
if (_refs.has(subject)) {
return;
}
fn(subject);
if (typeof subject === "object" && subject) {
_refs.add(subject);
for (const key in subject) {
execRecursively(fn, subject[key], _refs);
}
_refs.delete(subject);
}
}
const foo = {
foo: "Foo",
bar: {
bar: "Bar",
},
};
foo.bar.baz = foo; // Circular reference!
execRecursively((obj) => console.log(obj), foo);
在此,WeakSet 在第一次執行時建立,並在每次後續函式呼叫時(使用內部 _refs 引數)傳遞。
物件的數量或它們的遍歷順序並不重要,因此 WeakSet 比 Set 更適合(且效能更好)來跟蹤物件引用,尤其是當涉及大量物件時。
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-weakset-objects |
瀏覽器相容性
載入中…