An overview of Maps in JavaScript and how they can make up for limitations that come with using objects.
In JavaScript, objects are one of the most commonly used data structures. They provide you with a way to organize and store data as key/value pairs. While this is the case they also come with some limitations that are worth pointing out. In this article, we’ll be going over what those limitations are and show how using the Map object vs regular objects can be more effective.
What is the Map object?
The Map object was first introduced with the ES6 version of JavaScript. Like regular objects, they can contain key, value pairs and allow you to add, retrieve, remove, and check for those keys and values.
To create a new instance of the Map object we can do so as the following:
const map = new Map([
["key", "value"]
]);
There are several built-in properties and methods that come with an instance of the Map object. These include but are not limited to some of the more common ones such as the following:
.set()
- Adds key, value pairs with the first argument being the key and second being the value.set(key, value)
.get()
- Retrieves a value linked to a key by passing in the specified key as the only argument.get(key)
.delete()
- Removes a key, value pair identified by the passed-in key name.delete(key)
.has()
- Checks whether or not a key, value pair exists and returns a boolean value. Takes in the key as the only argument.has(key)
.size
- Returns an integer representing the number of key/value pairs contained within the Map object
For more about the Map object’s built-in properties and methods check out this link.
Using Map to avoid limitations of using objects
To show how using the Map object can solve for limitations that arise when using objects let’s go over what these limitations are and how we can avoid them using maps.
Objects are not guaranteed to be ordered
Although this has changed since JavaScript has updated to ES6 the ordering for the key/value pairs of a regular object can still be unreliable.
Take the following object we declared for example:
const obj = {
1: 2,
0: false,
"Greet": "Hello World",
a: "b",
c: "c"
}
When we log obj
to the console it displays a different ordering from what we originally declared it with:
{0: false, 1: 2, Greet: 'Hello World', a: 'b', c: 'c'}
When we try declaring the same key/value pairs with a map,
const map = new Map([
[1, 2],
[0, false],
["Greet", "Hello World"],
["a", "b"],
["c", "c"]
]);
we instead get the original order in which they were declared.
{1 => 2, 0 => false, 'Greet' => 'Hello World', 'a' => 'b', 'c' => 'c'}
No method to quickly determine the length or size of an object
With an object, we determine the size manually by iterating over the object using a for loop and a counter or using the Object.entries()
method along with .length
.
const obj = {
1: "one",
2: "two",
3: "three"
};
Object.entries(obj).length; // 3
When we need to find out the number of key/value pairs in a Map object we can use the .size
property to easily get it.
const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"]
]);
console.log(map.size); // 3
Map object is naturally iterable, Object is not
To iterate over objects we usually use a for..in loop to manually get each key and value.
// obj = {1: 'one', 2: 'two', 3: 'three'}
for (let key in obj) {
console.log(key, ": ", obj[key]);
// 1: one
// 2: two
// 3: three
}
Note however that Object.keys()
and Object.values()
or Object.entries()
can also be used to make an object iterable.
Object.entries(obj)
.forEach(entry => console.log(entry[0], ": ", entry[1]));
// 1: one
// 2: two
// 3: three
A map object can be easily and directly iterated over with methods like .forEach()
to access each value.
// map = {1 => 'one', 2 => 'two', 3 => 'three'}
map.forEach(value => console.log(value));
// one
// two
// three
Key types of objects can be only string or symbol
When declaring Javascript objects, the only types we can use as the key is a string or a symbol.
const obj = {
["key"]: "value"
};
console.log(obj); // automatically converts array key to a symbol: {key:'value'}
const obj2 = {
["key"]: "value",
function key(), "Value"
};
console.log(obj2); // throws an error
While keys for a regular JavaScript object can only be either a string or a symbol the same does not go for Map objects. For the Map object, its keys can be of any type including functions, objects, and arrays.
const map = new Map([
[ ["key"], "value" ],
[ function key() {}, "value" ],
[ { "a": 1 }, "b" ],
]);
console.log(map);
// {Array(1) => 'value', ƒ => 'value', {…} => 'b'}
Summary
In Javascript, Maps are very useful data structures. They provide more flexibility than regular objects do, for example, Maps give us the ability to use any data type as a key while also maintaining the original ordering they’re declared with.
Next time you’re reaching for that plain ol’ JavaScript object to store some sort of complex data, consider using a map. Depending on the use case it may just serve you better!
Top comments (0)
Some comments have been hidden by the post's author - find out more