我試圖理解WeakSet檔案here給出的例子。
// Execute a callback on everything stored inside an object
function execRecursively(fn, subject, _refs = null){
if(!_refs)
_refs = new WeakSet();
// Avoid infinite recursion
if(_refs.has(subject))
return;
fn(subject);
if("object" === typeof subject){
_refs.add(subject);
for(let key in subject)
execRecursively(fn, subject[key], _refs);
}
}
const foo = {
foo: "Foo",
bar: {
bar: "Bar"
}
};
foo.bar.baz = foo; // Circular reference!
execRecursively(obj => console.log(obj), foo);
在檔案中它說:
WeakSet 是弱的,這意味著對 WeakSet 中物件的參考是弱持有的。如果 WeakSet 中存盤的物件不存在其他參考,則可以對這些物件進行垃圾回收。
物件foo是在execRecursively函式之外定義的。WeakSet 是在其中定義的。因此,存在Weakset對函式范圍之外的物件的參考。
該檔案繼續:
物件的數量或它們的遍歷順序是無關緊要的,因此 WeakSet 比 Set 更適合(和高效)跟蹤物件參考,尤其是在涉及大量物件的情況下。
現在,我的問題是這段代碼如何比Set使用a 時的性能更高?因為,即使在當前示例中,也存在對 的參考,foo這會阻止垃圾收集器洗掉物件。
uj5u.com熱心網友回復:
這段代碼如何比
Set使用a 時的性能更高?
就像檔案說的那樣, aWeakSet不會跟蹤物件的數量或它們在集合中的順序,因此開銷要少一點。
在當前示例中,有一個對 的參考,
foo它阻止垃圾收集器洗掉物件。
是的,但是這是特定于您的示例的。當物件在遍歷結構時延遲生成時,弱點才會變得有趣(和有用)。請參閱以下示例:
function generate(n) {
if (n <= 0) return foo;
else return {
value: "x".repeat(n),
get next() { return generate(n-1); },
}
}
const foo = generate(100000);
let sum = 0;
execRecursively(obj => { sum = obj.value.length, foo);
console.log(sum);
如果execRecursively要使用 a Set,則在執行期間它需要在記憶體中保留十萬個包含很長字串的物件。使用 a 時WeakSet,物件可能已經在執行期間被垃圾收集。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/362459.html
標籤:javascript
