Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Maps

Spread the love

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at some data structures that we should use in our code to make our code easier to understand.

Use Plain Objects for Dictionaries

If we want to use JavaScript objects for dictionaries and maps, then it’s a good idea to create a plain object that has no prototype before we use them as such.

To do this, we can create a plain object with Object.create method that’s has null as the argument.

For instance, we can create a plain object as follows:

const obj = Object.create(null);
obj['foo'] = 1;
obj['bar'] = 2;

Then when we log:

console.log(obj.__proto__)

Then we see that __proto__ is undefined , so we see that obj doesn’t have any prototype.

Now it’s safe to use any kind of loop or method to loop through the properties like for...in , Object.keys , or Reflect.ownKeys to loop through the keys of the object without accidentally stumbling onto keys of their prototype.

Use Maps to Store Key-Value Pairs With String or Non-String Keys

With ES2015, we have the new Map object. A good feature of the Map object is that we can add keys that aren’t strings in addition to strings.

We can also use the for...of loop to loop through a Map object since it’s an iterable object.

The equality of the keys is determined by the SameValueZero algorithm. With SameValueZero, it’s mostly the same as the === operator, except that +0 isn’t the same as 0 and -0 isn’t the same as 0.

Another good feature of maps is that keys in a Map are ordered. The entries in a Map is returned in the order of their insertion.

It also performs better in scenarios where there are frequent additions and removals of key-value pairs.

Also, it has methods for clearing the Map and the size property for getting the size.

We can also safely check if an entry exists by the key with the has method.

For instance, we can create a map as follows:

const foo = {
  a: 1
};
const bar = {
  b: 1
};
const map = new Map();
map.set(foo, 1);
map.set(bar, 1);

In the code above, we have the foo and bar objects, which we use as keys. This can’t be done without Map s.

Once we defined foo and bar as keys, then we call set to add the entries with foo and bar as keys with some number as values.

Then we can call methods like clear to clear all key-value pairs of the Map object.

delete can with the key be used to remove an entry with the given key. For instance, we can use it as follows:

const foo = {
  a: 1
};
const bar = {
  b: 1
};
const map = new Map();
map.set(foo, 1);
map.set(bar, 1);
map.delete(bar);

Then we won’t see the 2nd entry anymore. We have to reference the objects directly since the SameValueZero compares objects by reference.

Another good feature is that we can use for...of to loop through a Map object. For instance, if we have the following Map :

const map = new Map();
map.set('a', 1);
map.set('b', 2);

Then we can loop through it as follows:

for (const [key, value] of map) {
  console.log(key, value);
}

In the code above, we used the destructuring syntax with the key and value destructured as an array.

We can retrieve the key and value of each entry this way. Therefore, we’ll see:

a 1
b 2

from the console log output.

We can also call the Map instance’s entries method to get the entries the same way:

for (const [key, value] of map.entries()) {
  console.log(key, value);
}

Also, we can get the array of keys with the keys method and the values with the values method as follows:

for (const key of map.keys()) {
  console.log(key);
}

for (const value of map.values()) {
  console.log(value);
}

Conclusion

We can create maps and dictionaries with the Object.create(null) call. Also, since ES2015, we can use the Map object, which can use non-string keys in addition to string and symbol keys.

Items in Map s are returned in the order they’re inserted so that the order is guaranteed. Also, there’re methods to check for values and iterating through them.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *