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