Understanding Key Differences Between JavaScript Objects and Maps
Written on
Chapter 1: Introduction to Objects and Maps
In JavaScript, both objects and maps serve as dynamic collections of key-value pairs. While they share some similarities, several distinct differences set them apart. This article delves into those differences.
Section 1.1: Construction Differences
The way we construct objects and maps varies significantly. The simplest method to create an object is through the object literal syntax:
const gamesObj = {
1: 'Citadels',
2: 'Tzolkin'
};
On the other hand, maps are instantiated using the built-in Map constructor:
const gamesMap = new Map([
[1, 'Citadels'],
[2, 'Tzolkin']
]);
For clarity, I will refer to key-value collections created with the object literal as "object maps" and those built with the Map constructor simply as "maps."
Section 1.2: Key Types in Objects vs. Maps
A fundamental difference lies in the types of keys used. In object maps, keys are restricted to strings. Conversely, maps allow keys of any data type. For instance, when a number is used as a key in an object literal, it converts to a string:
console.log(gamesObj[1]); // 'Citadels'
console.log(gamesObj['1']); // 'Citadels'
In contrast, maps distinguish between the number 1 and the string '1':
console.log(gamesMap.get(1)); // 'Citadels'
console.log(gamesMap.get('1')); // undefined
Thus, both structures maintain unique keys, ensuring no duplicates exist.
Section 1.3: Prototype Inheritance in Object Maps
Another notable difference is that objects created with the object literal inherit properties from the Object.prototype, leading to potential unexpected key-value pairs. For instance:
const mapObject = {};
console.log(mapObject['toString']); // ƒ toString() { [native code] }
To avoid this, one might use Object.create(null) to create an object without a prototype:
const mapObject = Object.create(null);
console.log(mapObject['toString']); // undefined
Section 1.4: Key Order Preservation
Maps are designed to maintain the order of their key-value pairs, whereas objects do not guarantee this. Consider the following object:
const gamesObj = {
2: 'Tzolkin',
1: 'Citadels',
};
const keys = Object.keys(gamesObj);
console.log(keys); // ["1", "2"]
In contrast, a similar map will preserve the insertion order:
const gamesMap = new Map([
[2, 'Tzolkin'],
[1, 'Citadels']
]);
const keys = gamesMap.keys();
console.log(keys); // MapIterator {2, 1}
Section 1.5: Accessing Entries
Accessing entries in object maps utilizes dot or bracket notation, while maps employ the get(key) method:
console.log(gamesObj[1]); // 'Citadels'
console.log(gamesMap.get(1)); // 'Citadels'
To check for the existence of keys, maps provide the has(key) method:
console.log(gamesMap.has(1)); // true
In contrast, objects utilize hasOwnProperty(key):
console.log(gamesObj.hasOwnProperty(1)); // true
Section 1.6: Adding and Deleting Entries
Adding new key-value pairs follows different methods. Maps use set(key, value), while objects utilize bracket or dot notation:
gamesMap.set(3, 'Catan');
gamesObj[3] = 'Catan';
To delete entries, maps offer the delete(key) method:
gamesMap.delete(1);
Whereas objects rely on the delete operator:
delete gamesObj[1];
Section 1.7: Size and Iteration
Maps maintain an updated size that can be accessed via the size property:
console.log(gamesMap.size);
For objects, size must be calculated using helper functions like Object.keys():
const size = Object.keys(gamesObj).length;
console.log(size);
Additionally, maps allow easy iteration with the forEach method:
gamesMap.forEach((value, key) => {
console.log(${key} - ${value});
});
Objects require the use of Object.entries() for iteration:
Object.entries(gamesObj).forEach(([key, value]) => {
console.log(${key} - ${value});
});
Chapter 2: JSON Support
It's worth noting that JSON supports object serialization but not maps. For example, with an object:
const gamesObj = {
1: 'Citadels',
2: 'Tzolkin'
};
const json = JSON.stringify(gamesObj);
console.log(json); // {"1":"Citadels","2":"Tzolkin"}
However, serializing a map results in an empty object:
const gamesMap = new Map([
[1, 'Citadels'],
[2, 'Tzolkin']
]);
const json = JSON.stringify(gamesMap);
console.log(json); // {}
Final Thoughts
In JavaScript, objects can be considered analogous to hash maps found in other programming languages. Both structures provide O(1) access time for retrieving keys, making them efficient for searching data. However, maps offer a more user-friendly interface for managing key-value pairs, especially when frequent additions and deletions occur. In contrast, if the sole purpose is to search for keys, an object map may suffice.
For further reading on objects, consider exploring "4 Ways to Create Objects in JavaScript."
Chapter 3: Additional Resources
This video titled "Maps vs. Objects in JavaScript - What's the Difference?" provides an insightful overview of the distinctions.
The second video, "JAVASCRIPT MAPS vs OBJECTS - 5 Differences Simplified," simplifies the key differences between these two structures.