Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
What is the specific meaning of strong and weak in reference? And why to introduce weak-reference WeakMap, and weak-reference WeakMap application
Implementation of Map in JavaScript
Map is implemented in JavaScript using 2 arrays, one for keys and the other for values. Map 4 apis are shared between 2 arrays: GET, set, HAS and DELETE. When set pushes a pair of values and keys to the end of two arrays, GET traverses the array of keys to get the index corresponding to the key to be queried, and then retrieves values from the index.
There are two problems with this
Time complexity problem
The time complexity is O(n)O(n)O(n), where n is the number of keys, because lookup traverses keys to search for matching keys.
Memory leak problem
For strong types, two keys and values need to be maintained in memory for a long time, which can cause a memory leak when other object references are empty because Map prevents objects from being garbage collected.
What is a weak reference
let wm1 = new WeakMap()
wm1.set("title"."machine learning")
// Uncaught TypeError: Invalid value used as weak map key
Copy the code
The value of key in WeakMap does not support basic data types, such as String, Number and other basic data types, but supports objects
mw1.set({},"value")
Copy the code
Why is there such a design, here is a little explanation for you. For example, we all need to have data associated with the DOM
const someThingDiv = document.querySelector("#box");
mw1.set({title:"machine learning"},someThingDiv)
Copy the code
WeakMap allows you to establish a relationship between data and DOM elements by using object keys as data and DOM elements as values.
When an object is used as a key in weakMap and there are no other references to the object, the object will be automatically erased from memory.
let m1 = new Map(a); tut_ml = {title:"machine learning"}
tut_dl = {title:"deep learning"}
m1.set(tut_ml,"machine learning tutorial");
m1.set(tut_dl,"deep learning tutorial");
tut_ml = null;
console.log(m1.size) / / 2
Copy the code
Even if tut_ML is set to null for a strongly referenced Map, the object will not be erased from memory because it is strongly referenced. So the m1 output is zero
let mw1 = new WeakMap(a); tut_ml = {title:"machine learning"}
tut_dl = {title:"deep learning"}
mw1.set(tut_ml,"machine learning tutorial");
mw1.set(tut_dl,"deep learning tutorial");
tut_ml = null
console.log(mw1) //
Copy the code
For weak references when you set the key to null the corresponding tut_mul in MW1 is also removed from the garbage collection mechanism.
Application scenarios
Additional data
The main application scenario of WeakMap is the storage of additional data. WeakMap comes in handy if you are working with an object that “belongs” to another file, or perhaps a third-party library, and want to store some data related to it, which should coexist with the object. Put the data into a WeakMap and use the object as the key of the data, then when the object is collected by the garbage collection mechanism, the data will also be cleared by the garbage collection mechanism.
This example is the classic WeakMap application scenario, that is, counting the number of visiting users, and counting the number of user visits with the user object as the key
let visitsCountWeakMap = WeakMap(a);function countUser(user){
let count = visitsCountWeakMap.get(user) || 0;
visitsCountWeakMap.set(user, count + 1);
}
Copy the code
The advantage is that when user is set to null, records accessed by that user are automatically cleared from visitsCountWeakMap.
let tony = { name: "Tony" };
countUser(tony); // Count the number of user accesses
tony = null;
Copy the code
Cache data
If you want to cache the same object with a Map < for multiple calls to the same object, you only need to calculate the result on the first call, and subsequent calls can be fetched directly from the cache. The disadvantage of using a Map is that you need to clean the cache when an object is no longer needed. If WeakMap is used instead of Map, this problem goes away and the corresponding cached results are automatically cleared from memory when the object is garbage collected.
let cache = new WeakMap(a);// Calculate and record the result
function process(obj) {
if(! cache.has(obj)) {let result = obj;
cache.set(obj, result);
}
return cache.get(obj);
}
let tut = {title:'machine learing'};
let result1 = process(tut);
let result2 = process(tut);
Copy the code