ES6 Set, WeakSet, Map and WeakMap

后端 未结 1 936
后悔当初
后悔当初 2020-12-15 14:36

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

相关标签:
1条回答
  • 2020-12-15 15:12

    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).

    0 讨论(0)
提交回复
热议问题