Understanding the Differences Between Map and WeakMap in JavaScript

·

5 min read

Understanding the Differences Between Map and WeakMap in JavaScript

Introduction

In JavaScript, Map and WeakMap are data structures that allow us to store and retrieve data more efficiently.

Map and Weakmap are a collection of <key,value> pairs.

In this article, we will explore the difference between these two data structures and how to use them in our code.

What is a Map in JavaScript?

A map stores data in the <key, value> form. The keys in a Map could be any value, including functions, objects, and primitives. Additionally, maps maintain the insertion order of <key-value> pairs and this helps us to iterate over them.

Operations that we can perform over a Map

The followings are the operations that we can perform over a map:

  • set(key, value) : It is used to add a new key-value pair.

  • get(key) : It is used to retrieve the value associated with a particular key.

  • has(key) : It is used to check if a particular key exists.

  • delete(key) : It is used to delete a particular key-value pair.

  • clear() : This method is used to remove all key-value pairs.

  • size() : It is used to get the number of key-value pairs in the map.

  • keys() : It is used to iterate over keys of the map.

  • values(): it is used to iterate over values of the map.

  • entries(): it is used to iterate over key-value pairs.

Let's understand with an example how to create a map and store data:

// create a map
let map = new Map();

let stringKey = 'apple';
let objectKey = {name: 'banana'};

let value1 = 'sweet';
let value2 = 'tart';

// store data
map.set(stringKey, value1);
map.set(objectKey, value2);

//get data 
console.log(map.get(key1)); // Output: 'sweet'
console.log(map.get(key2)); // Output: 'tart'

// Iterate over map
for(let [k, v] of map.entries()){
    console.log(k, v);
}
// Output: "apple" "sweet"
// Output: Object { name: "banana" } "tart"

In the above example, we created a map and added two key-value pairs. The types of keys are string and object.

What is a WeakMap in JavaScript?

A Weakmap also stores data in the form of <key-value> pairs similar to maps, however, it has a few differences from maps.

  • First, keys in a WeakMap can only be objects, not primitives or functions.

  • Second, weak maps don't maintain the insertion order of <key,value> pairs, and we can't iterate over them.

  • Finally, weak maps have a unique feature that allows keys to be garbage collected if there are no other references to them in the program.

Operations that we can perform over a WeakMap

The followings are the operations that a WeakMap supports:

  • set(key, value) : It is used to add a new key-value pair.

  • get(key) : It is used to retrieve the value associated with a particular key.

  • has(key) : It is used to check if a particular key exists.

  • delete(key) : It is used to delete a particular key-value pair.

  • clear() : This method is used to remove all key-value pairs from the weak maps.

Here is an example of how to create a weak map and add <key,value> pairs:

let weakMap = new WeakMap();
let key1 = {};
let key2 = {};

weakMap.set(key1, 'value1');
weakMap.set(key2, 'value2');

// check if a key-value pair exists
console.log(weakMap.has(key1)); // output: true

//Retrieve data 
console.log(weakMap.get(key1)); // Output: 'value1'
console.log(weakMap.get(key2)); // Output: 'value2'

// delete kay-value pair
weakMap.delete(key1);

// clear all key-value pairs
weakMap.clear();

// We can't iterate over weakmap.
for(let [k, v] of weakMap.entries()){
  console.log(k, v);
}
// Output: Error: weakMap.entries is not a function or its return value is not iterable

In the above example, we created a weak map and added two key-value pairs. Notice that the type of keys is an object.

Differences between Map and WeakMap

Now that we have understood Map and WeakMap, let's compare the differences between them:

  • Keys: Maps can have any value as a key, including functions, objects and primitives. Weak maps can only have objects as keys.

  • Orders: Maps maintain the insertion order of key-value pairs, while weak maps do not.

  • Iteration: Maps can be iterated over using methods like, keys(), values() and entries(). Weak maps can't be iterated over.

  • Garbage Collection: Weak map has a unique feature that allows keys to be garbage collected if there are no other references to them in the program. This is not possible with maps, as keys are always strongly referenced.

let weakMap = new WeakMap();
let key = {};
weakMap.set(key, "some value");
// if key object is set to null anywhere in our code, then weakMap will automatically remove key-value pair from the weakMap.

key = null; 

// Now, key object has no other reference, so weakMap will automatically remove the key and its corresponding value from the weakMap. 

// On the other hand, Map's keys are strongly referenced. Even if keys are set to null, Map will still contain key-value pair.


let map = new Map();
let key2 = {};
map.set(key2, "Some value");
key2  = null; // set key2 object reference to null

// At this point, key2 doesn't have any reference, but map still has key2 and its corresponding value;

// we can check map key and values using map.entries() method
for(let [k,v]  of map.entries()){
  console.log(k,"->", v);
}
// Output : Object {  } -> "Some value"

When to Use Map vs WeakMap

Let's explore when to use Map and WeakMap in our code:

  • Map: We can use it when we want to store key-value pairs and keys can be any value.

  • WeakMap: This can be useful in cases when we don't need to iterate over the key-value pairs and the keys are objects that have weak references.

Conclusion

So overall maps and weak maps are data structures that helps us to store data in the form of key-value, and they make it easy to store and retrieve data in efficient manner.