Since the introduction of modern JavaScript with ES5 and later ES6, common language patterns and structures were introduced that lifted the limited expressive power of the original JavaScript language to the level of more robust programming languages.
This ranges from syntactic sugar such as classes, async/await and arrow functions, to new language features such as variable scope, generators and destructuring.
In this blog post, I would like to focus on two important new standard types in Javascript: Map and Set. Although these data types have existed in some form or another in many languages, in Javascript they were always implemented using some form of ad-hoc Objects and Arrays.
When you are maintaining a large code base which was developed over a longer period of time, you may still come across code that doesn't use these modern data types, but could heavily benefit from it.
For those of you who are wondering if you can use it in your project: these types have been part of ES6 since 2015, so they are supported in all the modern browsers (and NodeJS). If you really need to support older browsers, there's always the Babel Polyfill
Map
First of all, Map. Generically speaking, a Map is a collection of data tuples (pairs) with a unique key and a value mapped to that key. A Map can be used to quickly look up data by its key.
Comparison with Object
Traditionally, this was achieved in JS with a plain object. There are, however, a couple of very important differences:
- keys in
Mapcan be of any type, in anObjectthey can only be simple types likeString,NumberandSymbol - keys in
Mapare only the ones you put in. In an Object, the prototype of theObjectalready adds some default keys, which may collide with your keys. - keys in
Mapare ordered by insertion. In anObject, there is no guaranteed order (at least not before ES2015) - a
Maphas asizeproperty, anObjectneeds manual calculation of its size - a
Mapis iterable, anObjecthas limitations on how to iterate (there is of coursefor..inbut only for enumerable properties) - a
Mapperforms better if the data set is dynamic, i.e., lots of additions and removals.Objectis not well suited for those scenarios.
Examples
Create
let obj = { id: 1, name: 'Test'}
let map = new Map(['id', 1], ['name', 'Test'])Check
obj.id !== undefined // true
map.has('id') // trueAdd
obj.language = 'en'
map.set('language', 'en')Remove
delete obj.id
map.delete('id')There is also Map.clear() which has no equivalent in Object. You would need to iterate over all properties.
Iterating
for (let key in obj) {
console.log(`${key}: ${obj[key]}`)
}
map.forEach((value, key) => {
console.log(`${key}: ${value}`)
})When to use
You could say, in general, an Object is suited for struct-like data types with fixed properties. They are easily serializable to JSON to be used in data exchange between systems.
A Map should be used whenever operations and transformations need to be performed on dynamic data sets, as it performs better in those use cases.
Set
Generically speaking, a Set is a collection of distinct data values.
Without a Set type, you would need to use an Array and check if a value was in it before adding it:
let arr = ['dog', 'cat', 'mouse']
function add(arr, value) {
if (arr.indexOf(value) === -1) {
arr.push(value)
}
}Even worse with removing:
function remove(arr, value) {
let index = arr.indexOf(value)
if (index >= 0) {
arr.splice(index, 1)
}
}All very error-prone!
With Set, this is all much more straight forward:
let set = new Set(['dog', 'cat'])
set.has('cat') // true
set.add('mouse')
set.delete('cat')Converting from Set to Array is also easy:
Array.from(set) // ['dog', 'mouse']
[...set] // ['dog', 'mouse']And we can now comfortably create set operations:
function union(setA, setB) {
let _union = new Set(setA)
for (let value of setB) {
_union.add(value)
}
return _union
}
function intersect(setA, setB) {
let _intersect = new Set()
for (let value of setA) {
if (setB.has(value)) {
_intersect.add(value)
}
}
return _intersect
}When to use
In general, whenever you need to be sure there is an actual set of data values with no duplicates, use Set.
In other cases, especially if you need an explicit order, keep using the good ole' Array.
Conclusion
Although these data types have been around for years in Javascript, chances are your existing code is still not using these powerful data types. If not: give them a try!
As always, we hope you liked this article and if you have anything to add, maybe you are suited for a Developer position in Notificare. We are currently looking for a Core API Developer, check out the job description. If modern Javascript is your thing, don't hesitate to apply!


