ES6 Set,WeakSet,Map and WeakMap [英] ES6 Set, WeakSet, Map and WeakMap

查看:143
本文介绍了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 that WeakMap, then that key/value pair is inaccessible and is automatically removed from the WeakMap.

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 the WeakMap 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆