DEV Community

Cover image for JavaScript Map, Set, WeakMap and WeakSet.
waelhabbal
waelhabbal

Posted on

JavaScript Map, Set, WeakMap and WeakSet.

JavaScript Map and Set

Map

A Map object is a collection of key-value pairs where each key can be of any type. This means that you can use objects, strings, numbers, or even functions as keys. A Map is similar to an object, but it provides additional functionality, such as built-in methods for adding, deleting, and updating key-value pairs.

Here's an example of how you can create a Map object:

const myMap = new Map();
Enter fullscreen mode Exit fullscreen mode

You can then add key-value pairs to the map using the set method:

myMap.set('key1', 'value1');
myMap.set('key2', 'value2');
myMap.set('key3', 'value2');//add same value
myMap.set("key2", "value3"); //add same key
Enter fullscreen mode Exit fullscreen mode

You can retrieve the value associated with a key using the get method:

console.log(myMap.get('key1')); // output: 'value1'
Enter fullscreen mode Exit fullscreen mode

You can also delete a key-value pair using the delete method:

myMap.delete('key1');
Enter fullscreen mode Exit fullscreen mode

Set

A Set object is a collectionof unique values where each value can be of any type. This means that you can use objects, strings, numbers, or even functions as values. A Set is useful when you want to store a collection of unique values and perform operations on them, such as finding the intersection or difference between two sets.

Here's an example of how you can create a Set object:

const mySet = new Set();
Enter fullscreen mode Exit fullscreen mode

You can then add values to the set using the add method:

mySet.add('value1');
mySet.add('value2');
mySet.add("value2");// add same value
Enter fullscreen mode Exit fullscreen mode

You can check if a value exists in the set using the has method:

console.log(mySet.has('value1')); // output: true
Enter fullscreen mode Exit fullscreen mode

You can also delete a value from the set using the delete method:

mySet.delete('value1');
Enter fullscreen mode Exit fullscreen mode

JavaScript Garbage Collection

Garbage collection in JavaScript is the process of automatically freeing up memory that is no longer being used by your code. This is important because JavaScript is a dynamically typed language, which means that you can create and destroy objects at runtime.

JavaScript engines use a technique called "mark and sweep" to perform garbage collection. This involves marking all the objects that are still being used by your code and then sweeping up the objects that are not marked. This process is performed periodically by the JavaScript engine and is completely transparent to your code.

Map vs WeakMap and when to use WeakMap

Map and WeakMap are both data structures in JavaScript, but they have some differences in terms of how they handle memory management.

A Map object holds strong references to its keys and values, which means that as long as the Map object exists, its keys and values will not be garbage collected. This can be useful in some cases, but it can also lead to memory leaks if you don't properly manage your Map objects.

On the other hand, a WeakMap object holds weak references to its keys. This means that if the only reference to a key is from the WeakMap object, the key will be automatically garbage collected. This can be useful in cases where you want to associate additional data with an object without keeping a strong reference to that object.

One common use case for WeakMap is in implementing private data for JavaScript objects. In JavaScript, there is no built-in support for private instance variables or methods, which can lead to issues with encapsulation and data hiding. However, WeakMap can be used to simulate private instance variables in JavaScript.

Here's an example:

      const privateData = new WeakMap();

      class Counter {
        constructor() {
          privateData.set(this, { counter: 0 });
        }

        increment() {
          const data = privateData.get(this);
          data.counter++;
          console.log(`Counter is now ${data.counter}`);
        }
      }

      let counter1 = new Counter();
      counter1.increment();
      counter1.increment();
      counter1.increment();
      let counter2   = new Counter();
      counter2.increment();

Enter fullscreen mode Exit fullscreen mode

In this example, we're using WeakMap to store private data for instances of MyClass. The privateData object is a WeakMap that maps instances of MyClass to an object containing the private data for that instance. The private data in this case is just a counter property that we're incrementing in the incrementCounter method.

Because privateData is a WeakMap, the private data for each instance of MyClass can be garbage collected when the instance itself is no longer reachable. This means that the private data is truly private to each instance of MyClass, and cannot be accessed from outside the class.

Another use case for WeakMap is in caching. For example, you could use a WeakMap to cache theresults of a time-consuming computation, where the keys are the arguments to the computation and the values are the results. Because WeakMap holds weak references to its keys, the cached results can be garbage collected when the arguments are no longer reachable, which can help to free up memory.

Here's an example:

const cache = new WeakMap();

function computeResult(arg) {
  if (cache.has(arg)) {
    console.log('Using cached result');
    return cache.get(arg);
  }

  console.log('Computing result');
  const result = /* perform time-consuming computation */;
  cache.set(arg, result);
  return result;
}
Enter fullscreen mode Exit fullscreen mode

In this example, we're using a WeakMap to cache the results of the computeResult function. The cache object is a WeakMap that maps arguments to results. When the function is called with a particular argument, we first check if the result is already cached. If it is, we return the cached result. If not, we perform the time-consuming computation to compute the result, and then cache the result in the WeakMap.

Because cache is a WeakMap, the cached results can be garbage collected when the arguments are no longer reachable, which can help to free up memory. This can be especially useful if the arguments are large objects or collections that take up a lot of memory.

Conclusion

In summary, Map and Set are useful data structures in JavaScript for storing collections of key-value pairs and unique values, respectively. JavaScript garbage collection is the process of automatically freeing up memory that is no longer being used by your code. Finally, Map and WeakMap have some differences in terms of how they handle memory management, with WeakMap being useful in cases where you want to associate additional data with an object without keeping a strong reference to that object.

Top comments (0)