This is my third article on getting started.

preface

Map and WeakMap are new collection types in Es6. Use key-value pair storage, you may think at this time, the Object Object also uses key-value pair storage, why still need these two Map and WeakMap key can be Object, and the key of Object can only be string. This definitely increases the possibilities for Map and WeakMap.

A, the use of

1. Use Map

The statement

Const map = new map () // Empty mapCopy the code

Set the value

map.set("key","value")
Copy the code

The values

map.get("key");
Copy the code

Check whether the key exists

map.has("key")
Copy the code

Remove the key

map.delete("key")
Copy the code

Loop through the map

Map. forEach(function(key){console.log("key",key) // Output map value})Copy the code
2. Use of WeakMap

The statement

const weakMap = new WeakMap();
Copy the code

Set the value

let key = {}
weakMap.set(key,"value")
Copy the code

The values

weakMap.get("key")
Copy the code

Check whether the key exists

weakMap.get("key")
Copy the code

Second, the difference between

You will find that there is no big difference between using upper WeakMap and Map, but it is important to note that WeakMap must be an Object when stored, or inherit the type of Object.

If only one key is invalid, an error is thrown, causing the entire initialization to fail

const weakMap2 = new WeakMap([ 
 [key1, "val1"], 
 ["BADKEY", "val2"], 
 [key3, "val3"] 
]); 
// TypeError: Invalid value used as WeakMap key 
typeof weakMap2; 
// ReferenceError: weakMap2 is not defined 
Copy the code

A WeakMap object is a set of key/value pairs where the keys are weakly referenced. This means that we cannot enumerate it and get its values.

What is a weak reference?

If the object is no longer referenced by other objects, the garbage collection mechanism automatically reclaims the memory occupied by the object.

For objects that are no longer in use, null can be used to override references to the corresponding object.

let obj = { key: "value" }; // obj is its reference obj = null; // The object will be erased from memoryCopy the code

But if we store an object in an array, just destroy the object, not destroy the array we can still get to the value of the object through the array.

let obj = { key: "value" }; let array = [ obj ]; obj = null; // Obj is stored in an array, so it is not collected by the garbage collection mechanism // We can get it through array[0]Copy the code

Similarly, 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 is not collected by garbage collection.

let obj = { key: "value" }; let map = new Map(); map.set(obj, "mapValue"); obj = null; // Obj is stored in map // use map.keys() to retrieve itCopy the code

Let’s see if we use WeakMap.

let obj = { key: "value" } let weakMap = new WeakMap() weakMap.set(obj, "mapValue") obj = null; Weakmap.keys () Weakmap.keys is not a functionCopy the code

Third, test WeakMap and Map.

node --expose-gc global.gc() process.memoryUsage(); // heapUsed: 4640360 ≈ 4.4m let map = new map () let key = new Array(60000) map.set(key, 1) global.gc() process.memoryUsage() // heapUsed: Key = null global.gc() process.memoryUsage() // heapUsed: Global.gc () process.memoryUsage() // heapUsed: approximately 44.6mbCopy the code

If you want Obj to be recycled, you need to delete(key) and then key = null.

Test again.

let map = new Map()
let key = new Array(60000)
map.set(key, 1)
map.delete(key)
key = null
Copy the code

node

node --expose-gc global.gc(); process.memoryUsage() // heapUsed: 4638376 ≈ 4.5m let map = new map () let key = new Array(60000) map.set(key, 1) global.gc() process.memoryUsage(); // heapUsed: 46727816 ≈ 44.6m map.delete(key) global.gc() process.memoryUsage() // heapUsed: 46727816 ≈ 44.6m map.delete(key) global.gc() process.memoryUsage() 46748352 ≈ 44.6m key = null; global.gc(); Process.memoryusage () // heapUsed: 4808064 ≈ 4.6mCopy the code

Let’s look at weakMap.

const weakMap = new WeakMap()
let key = new Array(5 * 1024 * 1024)
weakMap.set(key, 'value')
key = null
Copy the code

When we set weakMap.set(key, ‘value), we actually set weakMap’s weak reference to the object referenced by key. However, let key = new Array(60000) establishes a strong reference of key to the referenced object, so the referenced object will not be reclaimed. However, when we set key = null, there is only weak reference of weakMap to the referenced object. The next time the garbage collection mechanism executes, the reference object will be collected.

The node test

node --expose-gc global.gc() process.memoryUsage() // heapUsed: Const weakMap = new weakMap () let key = new Array(5 * 1024 * 1024) Weakmap. set(key, 1) global.gc() process.memoryUsage() // heapUsed: about 44.6M key = null global.gc() process.memoryUsage() // heapUsed: About 4MCopy the code

So WeakMap can save you the step of manually deleting the object’s associated data. WeakMap keeps a weak reference to the object referenced by the key name, that is, the garbage collection mechanism does not take that reference into account. As soon as all other references to the referenced object are cleared, the garbage collection mechanism frees the memory occupied by the object.

Four, use scenarios

DOM node metadata

Because the WeakMap instance does not interfere with garbage collection, it is a good fit for storing associated metadata.

Const m = new Map(); const loginButton = document.querySelector('#login'); // Associate the node with some metadata m.set(loginButton, {disabled: true});Copy the code

Suppose that after the above code is executed, the page has been changed by JavaScript and the original login button has been removed from the DOM tree. But because the reference to the button remains in the map, the corresponding DOM node remains in memory unless it is explicitly removed from the map or until the map itself is destroyed.

If a weak mapping is used here, as shown in the following code, the garbage collector can immediately free the memory of the node as soon as it is removed from the DOM tree (assuming there is no other reference to the object)

const weakMap = new WeakMap(); Weakmap. set(loginButton, {disabled: true}) const loginButton = document.querySelector('#login') // Associate some metadata with weakmap. set(loginButton, {disabled: true})Copy the code

Five, conclusion

  • weakMapIs to provide developers with a proactive way to resolve memory reclamation.
  • weakMapYou cannot include unreferenced objects, otherwise they will be automatically cleared.
  • WeakMapObject is not enumerable and cannot get the size of the collection.
  • WeakMapThere are only four methods available:get(),set(),has(),delete().

Reference: segmentfault.com/a/119000001…