As we know, in JavaScript garbage collection, the JavaScript engine stores values in memory when they are accessible. But when the reference disappears, the value is reclaimed.
// The object can be accessed, and coolFish is its reference
let people = { name: "coolFish" };
// Override the reference
people = null;
// The object will be removed from memory
Copy the code
But if you put an object in an array, the object exists as long as the array is there, even if there is no reference to the object.
let people = { name: "coolFish" };
let array = [ people ];
people = null; // Override the reference
// The object referenced earlier by people is stored in array
// So it will not be collected by garbage collection
Copy the code
If we use an object as the key of a regular Map, then when the Map exists, that object will also exist. It takes up memory and should not be collected.
WeakMap
The first difference between a WeakMap and a Map is that the key of a WeakMap must be an object, not the original value.
let people = { name: "coolFish" };
let weakMap = new WeakMap(a); weakMap.set(people,"ok"); // Work correctly (object as key)
weakMap.set("test"."Whoops"); // Error because "test" is not an object
people = null; // Overwrite references // people are removed from memory!
Copy the code
We can see that if people exist only as a WeakMap key, they will be automatically removed from the map. WeakMap does not support iteration and keys(), values() and entries() methods. So there is no way to get all the keys or values of WeakMap. We can use the following ways to get some of the information we want
- Weakmap. get(key), takes the value of the key.
- WeakMap. Set (key,value), sets weakMap
- Weakmap. delete(key), deletes the value according to the key
- Weakmap. has(key), whether the key is included
The reason for this limitation is that when the object in weakMap loses all its references, it will start automatic garbage collection. Garbage collection may be collected immediately, or there may be many collection tasks currently, so the collection will be delayed, so that we do not know when ** will be collected **. Therefore, methods that access all key values of WeakMap are not supported.
WeakMap Usage scenarios
The main application scenario of WeakMap is the storage of additional data. For example, we are dealing with an object belonging to another code, and want to store some related data, then these data should coexist with this object, at this time WeakMap is what we need, we put these data into WeakMap, and use the object as the key of these data. When the object is garbage collected, the data is also collected, and when the data does not exist, the object is also collected.
Let’s look at a caching example
// First we create a cache function
let cache = new Map(a)// Calculate and remember the result
function process(obj) {
if(! cache.has(obj)) {let result = obj;
cache.set(obj, result);
}
return cache.get(obj);
}
// We use it in other files
let obj = {/* Suppose we have an object */};
let result1 = process(obj); // The calculation is complete
/ /... Later, from another part of the code...
let result2 = process(obj); // The result to be remembered from the cache
/ /... Later, when we no longer need this object:
obj = null;
alert(cache.size); // 1 (oh! The object is still in cache and occupying memory!
Copy the code
Summary: We can see that when we apply the cache function, we pass the object as the map key, so when we initialize the object, it will still be in the cache because it is defined as the key in the cache.
To solve this problem, we can use WeakMap so that when the key object is not accessible, even if it is the key, it will be deleted from memory.
WeakSet
- with
Set
Similar, but we can only askWeakSet
Add objects (not raw values). - Objects can stay in a set only if they can be accessed somewhere else.
- with
Set
The same,WeakSet
supportadd
.has
和delete
Method, but not supportedsize
和keys()
, and cannot be iterated.
We can add objects to WeakSet to remove weights, and it does garbage collection when objects are not readable.
let visitedSet = new WeakSet(a);let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
visitedSet.add(john); John paid us a visit
visitedSet.add(pete); // Then Pete
visitedSet.add(john); // John visits again
// visitedSet now has two users
// Check whether John has visited.
alert(visitedSet.has(john)); // true
// Check whether Mary has called.
alert(visitedSet.has(mary)); // false
john = null;
// visitedSet will only be Pete
Copy the code
conclusion
WeakMap is a map-like collection that only allows objects as keys and removes them along with their associated values if they are not otherwise accessible. A WeakSet is a set-like collection that stores only objects and removes them if they are not otherwise accessible. None of them supports methods and attributes that reference all keys or their counts. Only one operation is allowed. WeakMap and WeakSet are used as “secondary” data structures in addition to the “primary” object store. Once an object is removed from main storage, it is automatically cleared if the object is only used as a key for a WeakMap or a WeakSet.