ES6 Set,WeakSet,Map and WeakMap [英] ES6 Set, WeakSet, Map and WeakMap
问题描述
已经有关于地图和弱地图的一些问题,如下所示: ES6 Map和WeakMap之间有什么区别?,但是我想问一下我应该在哪种情况下使用这些数据结构?或者当我偏爱一个人时,我应该考虑什么?
以下数据结构示例: https:// github.com/lukehoban/es6features
//设置
var s = new Set();
s.add(hello)。add(goodbye)。add(hello);
s.size === 2;
s.has(hello)=== true;
//映射
var m = new Map();
m.set(hello,42);
m.set(s,34);
m.get(s)== 34;
// Weak Maps
var wm = new WeakMap();
wm.set(s,{extra:42});
wm.size === undefined
// Weak Sets
var ws = new WeakSet();
ws.add({data:42});
//因为添加的对象没有其他引用,它不会被保存在集合
奖金。以上哪些数据结构将产生相同/相似的结果: let hash = object.create(null); hash [index] = something;
这在§23.3的规范:
< blockquote>
如果正在用作 WeakMap
键/值对的键的对象只能通过遵循一系列引用在 WeakMap
中,那么该键/值对是无法访问的,并自动从 WeakMap
中删除。
因此,弱地图中的条目(如果它们的键未被其他任何参数引用)将在某些时候通过垃圾回收进行回收。 p>
相比之下, Map
持有对其键的强大引用,从而阻止它们如果地图是唯一引用它们的地方,垃圾回收。
MDN 如下所示:
WeakMap
弱势。这意味着,如果没有其他对密钥的强烈引用,则整个条目将从垃圾回收器的WeakMap
中删除。
And WeakSet
也是一样的。
< blockquote>
...在哪种情况下我应该喜欢使用这种数据结构?
任何情况你不希望有一个地图/设置使用一个键来阻止该密钥被垃圾回收的事实。
一个例子,当你可以使用这个将是具有真实私有的实例特定信息,如下所示:
让Thing =(( )=> {
var privateData = new WeakMap();
class Thing {
constructor(){
privateData [this] = {
foo:some value
};
}
doSomething(){
的console.log(privateData [此]包含.foo);
}
}
return Thing;
})();
该范围函数以外的代码无法访问 privateData中的数据
。该数据由实例本身键入。你不会没有一个 WeakMap
,因为如果你有内存泄漏,你的 Thing
永远不会被清理但是, WeakMap
仅保存弱引用,因此,如果使用 Thing
实例的代码是完成它并释放其对实例的引用, WeakMap
不会阻止实例被垃圾回收;相反,实例键入的条目从地图中删除。
以上哪些数据结构将产生相同/相似的结果做:
let hash = Object.create(null); hash [index] = something;
最接近 / code>,因为字符串
index
(属性名称)将由对象中的强引用持有(它及其关联的属性将不会被回收,如果没有别的参考)。
There is already some questions about map and weak maps, like this: What's the difference between ES6 Map and WeakMap? but I would like to ask in which situation should I favor the use of these data structures? Or what should I take in consideration when I favor one over the others?
Examples of the data structures from:https://github.com/lukehoban/es6features
// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined
// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references, it will not be held in the set
Bonus. Which of the above data structures will produce the same/similar result of doing: let hash = object.create(null); hash[index] = something;
This is covered in §23.3 of the specification:
If an object that is being used as the key of a
WeakMap
key/value pair is only reachable by following a chain of references that start within thatWeakMap
, then that key/value pair is inaccessible and is automatically removed from theWeakMap
.
So the entries in a weak map, if their keys aren't referenced by anything else, will be reclaimed by garbage collection at some point.
In contrast, a Map
holds a strong reference to its keys, preventing them from being garbage-collected if the map is the only thing referencing them.
MDN puts it like this:
The key in a
WeakMap
is held weakly. What this means is that, if there are no other strong references to the key, then the entire entry will be removed from theWeakMap
by the garbage collector.
And WeakSet
does the same.
...in which situation should I favor the use of this data structures?
Any situation where you don't want the fact you have a map/set using a key to prevent that key from being garbage-collected.
One example of when you might use this would be to have instance-specific information which was truly private to the instance, which looks like this:
let Thing = (() => {
var privateData = new WeakMap();
class Thing {
constructor() {
privateData[this] = {
foo: "some value"
};
}
doSomething() {
console.log(privateData[this].foo);
}
}
return Thing;
})();
There's no way for code outside that scoping function to access the data in privateData
. That data is keyed by the instance itself. You wouldn't do that without a WeakMap
because if you did you'd have a memory leak, your Thing
instances would never be cleaned up. But WeakMap
only holds weak references, and so if your code using a Thing
instance is done with it and releases its reference to the instance, the WeakMap
doesn't prevent the instance from being garbage-collected; instead, the entry keyed by the instance is removed from the map.
Which of the above data structures will produce the same/similar result of doing:
let hash = Object.create(null); hash[index] = something;
That would be nearest to Map
, because the string index
(the property name) will be held by a strong reference in the object (it and its associated property will not be reclaimed if nothing else references it).
这篇关于ES6 Set,WeakSet,Map and WeakMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!