7 Differences between Objects and Maps in JavaScript

7 Differences between Objects and Maps in JavaScript

Cristian Salcescu
Photo by the author

Objects and maps are both dynamic collections of key-value pairs.

Starting from this definition they are pretty similar but there are some differences between them we are going to find out.

1. The construction is of course different

The object literal syntax is the simplest way to create an object map in JavaScript.

const gamesObj = {
  1: 'Citadels',
  2: 'Tzolkin'  
};

Maps are created using the built-in Map constructor.

const gamesMap = new Map([
  [1, 'Citadels'],
  [2, 'Tzolkin']
]);

From now on I am going to use the words “object” or “object maps” for key-value collections created using the object literal syntax and the word “maps” for maps build with the Map built-in constructor.

2. Keys on objects are strings, on maps keys are of any type

Indeed objects are collections of key-value pairs but the key can only be a string. While the key of a Map can be of any type.

If for example, we use a number as a key in an object literal, that number is converted to a string and used as the key.

Because the key is converted to a string we get the same result when trying to get value for the 1 number value or for the '1' string value.

console.log(gamesObj[1]);
//'Citadels'

console.log(gamesObj['1']);
//'Citadels'

When using maps the key can be of any type so the 1 number key is different from the '1' string key.

console.log(gamesMap.get(1));
//'Citadels'

console.log(gamesMap.get('1'));
//undefined

The key is unique in both cases. There cannot be two properties in an object with the same key or two entries in a map with the same key.

3. Object maps inherit unwanted keys from the prototype

Another difference is that objects created with the object literal have a set of unexpected key-value pairs from the Object.prototype.

When we print the Object.prototype you can see it has a few properties like hasOwnPropertyisPrototypeOftoLocaleStringtoString.

console.log(Object.prototype);

An object created with the object’s literal syntax will have all these property keys on it. So the empty object {} is not really empty. Check the code below.

const mapObject = {};
console.log(mapObject['toString']);
//ƒ toString() { [native code] }

We created an “empty object” and were able to access the toString key on it.

A better option for creating object maps is to use the Object.create(null)utility.

const mapObject = Object.create(null);

console.log(mapObject['toString']);
//undefined

Object.create(null) builds an object with no prototype.

4. Maps preserve the order of their keys, objects do not

The original order of key-value pairs is preserved in maps, while in objects it is not.

const gamesObj = {
  2: 'Tzolkin',
  1: 'Citadels',
};
const keys = Object.keys(gamesObj);
console.log(keys);
//["1", "2"];
const keyValuePairs = Object.entries(gamesObj);
console.log(keyValuePairs);
//["1", "Citadels"]
//["2", "Tzolkin"]

Notice that when the object is created the key 2 comes before the key 1. When retrieving all the keys 2 comes after 1.

Below is a similar collection built with the Map constructor. This time the initial order is preserved.

const gamesMap = new Map([
  [2, 'Tzolkin'],
  [1, 'Citadels']
])
const keys = gamesMap.keys();
console.log(keys);
//MapIterator {2, 1}
const keyValuePairs = gamesMap.entries();
console.log(keyValuePairs);
//MapIterator {2 => "Tzolkin", 1 => "Citadels"}

5. Maps offer a nicer interface for accessing entries

Getting

Accessing properties on an object is done using the dot or the bracket notation. In our case because the initial key was a number we can only use the bracket notation.

gamesObj[1];
//'Citadels'

When the key is the valid variable name we can use the dot notation also. Check the next example.

const anotherGamesObj = {
  id1: 'Citadels',
  id2: 'Tzolkin'  
};
console.log(anotherGamesObj.id1);
//'Citadels'

On maps, we can retrieve a value using the get(key) method.

gamesMap.get(1);
//'Citadels'

Checking if a key exists

Checking if a key is already in a map is done using the has(key) method.

gamesMap.has(1);
//true

gamesMap.get(3);
//false

On objects, we can use the hasOwnProperty(key) method.

gamesObj.hasOwnProperty(1);
//true

gamesObj.hasOwnProperty(3);
//false

Adding

Adding a new key-value pair on a map is done using the set(key, value)method.

gamesMap.set(3, 'Catan'); 
//{1=>'Citadels', 2=>'Tzolkin', 3=>'Catan'}

Again for objects, we use the bracket or the dot notation for adding new properties.

gamesObj[3] = 'Catan';
//{ 1: 'Citadels', 2: 'Tzolkin', 3: 'Catan'};

Deleting

Maps have the delete(key) method for deleting pairs.

gamesMap.delete(1);

On objects, we can use the delete operator.

delete gamesObl[1];

Reading the size

Maps keep their size updated so we can get the size using the sizeproperty.

console.log(gamesMap.size);

Here is how we can test for emptiness on a map.

gamesMap.size === 0

Objects do not have a specific method for getting the size. We need to use external helpers functions like Object.keys().

const size = Object.keys(gamesObj).length;
console.log(size);

6. Objects require helpers functions for accessing the key-values pairs

We can iterate over the entries in a map using the forEach method.

const gamesMap = new Map([
  [1, 'Citadels'],
  [2, 'Tzolkin']
]);
gamesMap.forEach((value, key)=>{
   console.log(`${key} - ${value}`)
  });
//1 - Citadels
//2 - Tzolkin

On objects, we can iterate using the Object.entries() helper function.

Object.entries() returns an array of [key, value] pairs with all the owned properties of an object. Once we have that we can use the array methods likes forEach.

const gamesObj = {
  1: 'Citadels',
  2: 'Tzolkin'  
};
Object
  .entries(gamesObj)
  .forEach(([key, value])=>{
    console.log(`${key} - ${value}`)
  });
//1 - Citadels
//2 - Tzolkin

7. JSON offers support for objects but not for maps

JSON supports objects but not maps.

const gamesObj = {
  1: 'Citadels',
  2: 'Tzolkin'  
};
const json = JSON.stringify(gamesObj);
console.log(json);
//{"1":"Citadels","2":"Tzolkin"}

Maps do not work with JSON. Serializing results in an empty object.

const gamesMap = new Map([
  [1, 'Citadels'],
  [2, 'Tzolkin']
]);
const json = JSON.stringify(gamesMap);
console.log(json);
//{}

Final Thoughts

Objects in JavaScript are what in other languages are called hash maps. Accessing keys in the map object has an O(1) access time, meaning that it takes a constant time to get the key, no matter the amount of data in the object map.

No matter how these key-value collections are created using the Mapconstructor or the object literal syntax they are mainly used for fast searching data. Both of them perform in O(1) access time. Retrieving a key does not require scanning through all of the data.

Maps offer a nicer interface for managing the key-value pairs. In scenarios that require adding and removing entries, Map is a better choice.

When creating the key-value collection nonce then used it just to search for keys an object map can be enough.

For more on objects, you can check out 4 Ways to Create Objects in JavaScript. Thanks for reading.

Origin source: https://medium.com/dailyjs/7-differences-between-objects-and-maps-in-javascript-bc901dfa9350




Report Page