WeakMap in Javascript

Introduction

Now that we have understood the concept of garbage collection and memory management in Javascript in the last blog I published, it is time to look at the two new data structures - weakMap and weakSet.

weakMap

  • weakMap is analogous to Maps in Javascript. The difference between the two is while maps supports keys of primitive types, weakMap only supports objects as keys.

  • Also, any object that has no reference to it becomes unreachable in memory and is removed from the weakMap. This is something that is different as compared to maps as in maps that object continues to live on in the memory even if the reference is lost. The object only becomes unreachable if the map is removed from the memory.

  • Let us look at the code snippet to below to understand how weakMap is used in Javascript

let weakMap = new WeakMap();

let obj = { name: "John" };

weakMap.set(obj, "ok");

weakMap.set("test", "ok"); // This is an error as the key can only be an object

obj = null; //There exists no reference to the object, it will be 
//automatically removed from the weakMap

Why do we need maps?

  1. Additional Data storage

    Imagine a scenario, where there exists some object associated with some other code, or a third-party library and we want to store some data associated with the object but we want the object to be removed from the memory, as soon as it becomes unreachable. In such a scenario, weakMap can do the work as a map is not a good option (the object even though it is dereferenced, continues to live on the memory as long as it is in the map).

    Let us say we want to keep track of the number of times, a user enters stores in a mall, and we want to remove this data, once the user exits the mall.

     let visitedCountMap = new WeakMap();
    
     function countVisits(user) {
         let count = visitedCountMap.get(user) || 0;
    
         visitedCountMap.set(user, count + 1);
     }
    
     let user = { name: "Nikhil" };
    
     countVisits(user);
    
     john = null;
    
  2. Caching

    Suppose we want to store a function's results so that future calls on the same object can reuse it.

     let cache = new Map();
    
     function process(obj) {
         if(!cache.has(obj)) {
             let result = obj;
    
             cache.set(obj, result);
         }
    
         return cache.get(obj);
     }
    
     let obj = {};
     let result1 = process(obj); //calculating the result
    
     let result2 = process(obj); //remembered result
    
     obj = null;
    

    The moment the reference to the object is lost, the cached result associated with the object is also lost.

Methods in weakMaps

    • All the methods supported for maps are also supported for weakMaps.

      • weakMap.set(key)
      let weakMap = new WeakMap();
      
      let user = { name: "John" };
      
      weakMap.set(user, "OK");
      
      • weakMap.get(key)
      let weakMap = new WeakMap();
      
      let user = { name: "John" };
      
      weakMap.set(user, "OK");
      
      console.log(weakMap.get(user));
      
      • weakMap.has(key)
      let weakMap = new WeakMap();
      
      let user = { name: "John" };
      
      weakMap.set(user, "OK");
      
      console.log(weakMap.has(user)); //This would return true;
      
      • weakMap.delete(key)
      let weakMap = new WeakMap();
      
      let user = { name: "John" };
      
      weakMap.set(user, "OK");
      
      weakMap.delete(user);
      
  • WeakMap doesn’t support certain iterables and methods - keys(), values(), entries(), size

    • This is because it is the Javascript engine that decides when this cleanup of unreachable objects should happen. It may occur immediately or it may happen at a later time. It could have happened partially too. So there is no way to know the exact size of the weakMap. Hence, no iterative methods.

Links

Below is the link, where you can find the source code related to the implementation of the above mentioned methods in Github. Do check it out for your reference.

Demonstration of the weakMap in Javascript

Final Thoughts

Not much to say today. Wait for my next blog on weakSet. Till then, Bye!

Follow me on GitHub and LinkedIn