An Introduction to the Map/Dictionary Data Structure in Javascript

Everything about Map Data Structure in Javascript

A Dictionary data structure is known by many names. It is often called Map, Associative Array, Symbol, or Lookup table. In Javascript, we have Objects, Map, and WeakMap which can all fall into this category but, do you know their difference and when to use which?

Video Version of This Article

This post is an improved and more detailed article version of the Dictionary Data Structure Series on Youtube that you can check if you prefer videos.

Watch Videos

What is a Dictionary?

A Dictionary is a data structure that stores key-value pairs. In a sense, if you know a key for the item, you can use it to access it. This is similar to Array and indexes relationship but dictionary items are stored differently. Besides this similarity, a dictionary is much closer to a Set data structure than an Array.

Javascript Object, Map, and WeakMap

In Javascript, developers use Objects as Dictionaries, and Objects store key-value pair data where the value can be anything and keys must be strings or symbols. With ES6 the community got Map and WeakMap which came to address very specific problems and some Object limitations.

Map vs Object

Whether you are aware of it or not, Objects are more of building blocks than a data structure. In Javascript, the idea behind Objects is much closer to a Class than it is to a Dictionary. As a matter of fact, class is just syntactic sugar on how to create objects and there are many other ways to do the same. This means that for years, Javascript developers did not have a proper Dictionary data structure.

There are Pros and Cons to both and they actually work great together but Map addresses few Object limitations nicely:

  • Key types:
    Object only accepts string or symbol keys and with Map, keys can be anything. This opens the door for so many possibilities like using DOM elements as a key and associate some specific data to them for quick access.
const itemsOrder = new Map();
const ul = document.querySelector('.items');
[...ul.children].forEach((li, index) => {
itemsOrder.set(li, index);
});
  • Size:
    An Object provides no way to find out about the number of things inside (another detail connecting it to the concept of class). On the other hand, Map comes with the “size” property you can easily find the number of items it contains. The workaround for Object has been using its static methods like, “keys”, “values”, and “entries” to get an array and access its length property.
const obj = {a: 10, b: 30, c: 100};
const map = new Map([['a', 10], ['b', 30], ['c', 100]]);
Object.keys(obj).length; // 3;
map.size; // 3
  • Iteration:
    Another limitation of Javascript Object is that it is not iterable. Because Map is the data structure, the need to iterate its items is built-in. You can use its “forEach” method or one of its iterators to go over the items.
const map = new Map([['a', 10], ['b', 30], ['c', 100]]);map.forEach((value, key) => {
console.log(value); // 10, 30, 100
console.log(key); // a, b, c
});
  • Key Order:
    Javascript Object order keys unreliably and Map will keep the order of insertion of items. Object keys are ordered but you should not rely on them because depending on how you read its keys and how you decide to iterate them, you may get different results.
  • Prototype Keys:
    When you create an object it already comes with its prototype and those keys count too. When you create a Map, what you put into it is separate from its prototype. That means that whatever the key name I pick, it will never collide with its prototype keys. This can be fixed by creating an object using “Object.create(null)” which creates an object without a prototype.
const map = new Map();
const obj = {};
// overrides original toString method
obj['toString'] = () => 10;
map.set('toString', () => 10;
obj.toString(); // 10
map.toString(); // [object Map]
map.get('toString')(); // 10
  • Performance:
    In general, Map does better in scenarios with constant set and removal of items. Because Object is not a data structure, it is not optimized for constant set and removal of items.

When to use Map vs Object?

When all you want is a lookup table, go with Map. It is also perfect for a big load of data and overall more performant when you are constantly setting and removing data. If you need a lookup table in which the keys need to be something other than string, Map is also your only option.

Even though Map is meant to be used as a data structure, Object works best with JSON and because of that, it is perfect for data transfer since it shares syntax with JSON. It is also better for small data exchange between functions with a much easier syntax, but that comes down to preference more than anything.

Another detail that makes it hard for Map usage is that most APIs and tools on the web was created to take objects rather than Map and making the conversion is not always easy or possible. Map fits better in an ecosystem where you control things and is creating a custom solution.

Because Javascript Object is meant more like a building block, there are many ways to create an Object in Javascript which you should be familiar with. In contrast, there is a single way to create a Map and a single purpose to use it. You should try it.

Map vs WeakMap

Along with Map, Javascript also has WeakMap. Its main difference is that it holds a weak reference to its items and the keys can only be objects, any object, and that goes for functions and other WeakMap or Map as well. Because of this weak nature, WeakMap is not iterable which also means you cannot access its size.

The advantage of WeakMap is that it will not prevent the garbage collector from doing its job. With Map, if it holds a reference to some object, even if you are not using that object, it will continue to be in memory until you dispose of the Map. This is true for any objects, Array, Object, Set, etc.

To put it simply, if you create object A and put it inside WeakMap and nothing else references it, the garbage collector will clear it from memory. WeakMap weak reference nature does not stop garbage collectors from clearing memory as other objects do.

Note: WeakMap is not the only way to create weak reference to things. You can create weak reference using Jasvascript WeakRef with other things in your code.

When to use WeakMap?

WeakMap is perfect when memory is a concern. If you are to hold reference of things that come to life and are cleared constantly, instead of collecting reference to them use WeakMap so they can be collected at an earlier convenient. WeakMap is notoriously used to prevent memory leaks.

It is also perfect as a tracker. This is because when tracking something you must keep a reference to them and if they no longer exist, why hold on to them? Another common use case is to create private members of objects and class although that can be accomplished easily natively now.

One last usage case example would be to extend a library or a DOM element with extra capabilities or data. You can actually use it to extend any native object or some other object as a way to attach metadata to them for later reference.

const elements = new WeakMap();elements.set(document.querySelector('button'), {
some: 'data'
});
document.onclick = e => {
// the event tagert to access
// data associated with the element

console.log(elements.get(e.target))
}

Conclusion

The take away from this is, you should use Map more to manage key-value pair data instead of Objects. Use Object for small data exchange, JSON for network data exchange, and WeakMap to hold weak references to things. Map is powerful and so much better in every way as a data structure.

Check this channel for more data structure articles like this.

YouTube Channel: Before Semicolon
Website: beforesemicolon.com

Blog & YouTube Channel for Web, UI & Software Development - beforesemicolon.comyoutube.com/c/BeforeSemicolon

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store