Rob*_*bok 52 javascript ecmascript-6 traceur
WeakSet应该通过弱引用来存储元素.也就是说,如果某个对象未被其他任何东西引用,则应该从WeakSet中清除它.
我写了以下测试:
var weakset = new WeakSet(),
numbers = [1, 2, 3];
weakset.add(numbers);
weakset.add({name: "Charlie"});
console.log(weakset);
numbers = undefined;
console.log(weakset);
Run Code Online (Sandbox Code Playgroud)
即使我的[1, 2, 3]
数组没有被任何引用引用,它也不会从WeakSet中删除.控制台打印:
WeakSet {[1, 2, 3], Object {name: "Charlie"}}
WeakSet {[1, 2, 3], Object {name: "Charlie"}}
Run Code Online (Sandbox Code Playgroud)
这是为什么?
另外,我还有一个问题.将对象直接添加到WeakSets有什么意义,如下所示:
weakset.add({name: "Charlie"});
Run Code Online (Sandbox Code Playgroud)
那些Traceur的故障还是我错过了什么?
最后,如果我们甚至无法迭代它并获得当前大小,那么WeakSet的实际用途是什么?
Ber*_*rgi 53
它没有从WeakSet中删除.这是为什么?
很可能是因为垃圾收集器还没有运行.但是,你说你正在使用Traceur,所以它可能是因为它们没有得到适当的支持.我想知道怎么console
能显示出来的内容WeakSet
.
直接向WeakSets添加对象有什么意义?
绝对没有必要向WeakSet
s 添加对象文字.
如果我们甚至无法遍历它并获得当前大小,那么WeakSet的实际用途是什么?
所有你能得到的只是一点信息:集合中是否包含对象(或一般来说,值)?
这在您想要"标记"对象而不实际改变它们(在它们上设置属性)的情况下非常有用.许多算法包含某种"如果x
已经看到"的条件(JSON.stringify
循环检测可能是一个很好的例子),当你使用用户提供的值时,建议使用Set
/ WeakSet
.这里的优点WeakSet
是,当你的算法仍在运行时,它的内容可以被垃圾收集,因此当你处理大量懒惰的数据(甚至可能是异步的)时,它有助于减少内存消耗(甚至防止泄漏)产生的.
Ben*_*aum 28
这是一个非常难的问题.说实话,我不知道在JavaScript的背景下,所以我在es escucuss中询问并得到了Domenic的令人信服的答案.
WeakSet对安全性和验证有用.如果你想能够隔离一段JavaScript.它们允许您标记对象以指示它属于一组特殊对象.
假设我有一节课ApiRequest
:
class ApiRequest {
constructor() {
// bring object to a consistent state, use platform code you have no cirect access to
}
makeRequest() {
// do work
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我正在编写一个JavaScript平台 - 我的平台允许您运行JavaScript来进行调用 - 进行您需要的调用ApiRequest
- 我只希望您ApiRequest
使用我给您的对象来创建,这样您就无法绕过任何约束我有位置.
但是,目前没有什么能阻止你这样做:
ApiRequest.prototype.makeRequest.call(null, args); // make request as function
Object.create(ApiRequest.prototype).makeRequest(); // no initialization
function Foo(){}; Foo.prototype = ApiRequest.prototype; new Foo().makeRequest(); // no super
Run Code Online (Sandbox Code Playgroud)
等等,请注意您不能保留正常的列表或ApiRequest
对象数组,因为这样可以防止它们被垃圾回收.除了关闭之外,任何事情都可以用Object.getOwnPropertyNames
或等公共方法来实现Object.getOwnSymbols
.所以你一个人,我做了:
const requests = new WeakSet();
class ApiRequest {
constructor() {
requests.add(this);
}
makeRequest() {
if(!request.has(this)) throw new Error("Invalid access");
// do work
}
}
Run Code Online (Sandbox Code Playgroud)
现在,无论我做什么 - 我必须持有一个有效的ApiRequest
对象来调用makeRequest
它的方法.没有WeakMap/WeakSet,这是不可能的.
简而言之 - WeakMaps对于在JavaScirpt中编写平台非常有用.通常这种验证是在C++方面完成的,但添加这些功能将允许在JavaScript中移动和制作内容.
(当然,映射值的所有内容WeakSet
也可以做,但对于任何map/set构造都是如此)WeakMap
true
(就像Bergi的回答所暗示的那样,没有理由将对象文字直接添加到a WeakMap
或a WeakSet
)
Tao*_*oPR 11
根据定义,WeakSet
只有三个关键功能
听起来更熟悉?
在某些应用程序中,开发人员可能需要实现快速迭代一系列数据的方法,这些数据受到大量冗余的污染,但您只想选择之前未处理过的数据(唯一).WeakSet可以帮到你.请参阅以下示例:
var processedBag = new WeakSet();
var nextObject = getNext();
while (nextObject !== null){
// Check if already processed this similar object?
if (!processedBag.has(nextObject)){
// If not, process it and memorize
process(nextObject);
processedBag.add(nextObject);
}
nextObject = getNext();
}
Run Code Online (Sandbox Code Playgroud)
上面应用程序的最佳数据结构之一是Bloom过滤器,它非常适合海量数据.但是,您也可以将WeakSet用于此目的.
“弱”集合或映射在您需要保留任意集合的东西时很有用,但您不希望它们在集合中的存在阻止这些东西在内存紧张时被垃圾收集。(如果确实发生了垃圾收集,“已收割”的对象将从收集中悄悄消失,因此您实际上可以判断它们是否消失了。)
例如,它们非常适合用作后备缓存:“我最近是否已经检索过此记录?” 每次你检索到一些东西时,把它放入地图中,知道JavaScript 垃圾收集器将负责为你“修剪列表”,并且它会自动这样做以响应普遍的内存条件(你可以' t 合理预期)。
唯一的缺点是这些类型不是“可枚举的”。您无法遍历条目列表 - 可能是因为这可能会“触及”这些条目,从而无法达到目的。但是,这是一个很小的代价(如果需要,您可以“围绕它编写代码”)。
归档时间: |
|
查看次数: |
10534 次 |
最近记录: |