Using the New ES6 Collections: Map, Set, WeakMap, WeakSet

By Kyle Pennell

This article is part of a web development series from Microsoft. Thank you for supporting the partners who make SitePoint possible.

Most major programming languages have several types of data collections. Python has lists, tuples, and dictionaries. Java has lists, sets, maps, queues. Ruby has hashes and arrays. JavaScript, up until now, had only arrays. Objects and Arrays were the workhorses of JavaScript. ES6 introduces four new data structures that will add power and expressiveness to the language: Map, Set, WeakSet, and WeakMap.

Let’s examine these four new collections and the benefits they provide.

Searching for the JavaScript HashMap

HashMaps, dictionaries, and hashes are several ways that various programming languages store key/value pairs and these data structures are optimized for fast retrieval.

In ES5, JavaScript objects–which are just arbitrary collections of properties with keys and values–can simulate hashes, but there are several downsides to using objects as hashes.

Downside #1: Keys must be strings in ES5

JavaScript object property keys must be strings, which limits their ability to serve as a collection of key/value pairs of varying data types. You can of course coerce/stringify other data types into strings, but this adds extra work.

Downside #2: Objects are not inherently iterable

Objects weren’t designed to be used as collections, and as a result there’s no efficient way to determine how many properties an object has (see, for e.g., Object.keys is slow). When you loop over an object’s properties, you also get its prototype properties. You could add the iterable property to all objects but not all objects are meant to be used as collections. You could use the for...in loop and the hasOwnProperty() method, but this just a workaround. When you loop over an object’s properties, the properties won’t necessarily be retrieved in the same order they were inserted.

Downside #3: Challenges with built-in method collisions

Objects have built in methods like constructor, toString, and valueOf. If one of these was added as a property, it could cause collisions. You could use Object.create(null) to create a bare object (which doesn’t inherit from object.prototype), but, again, this is just a workaround.

ES6 includes new collection data types, so there is no longer a need to use objects and live with their drawbacks.

Using ES6 MapCollections

Map is the first data structure/collection we’ll examine. Maps are collections of keys and values of any type. It’s easy to create new Maps, add/remove values, loop over keys/values and efficiently determine their size. Here are the crucial methods:

Creating a map and using common methods

Example code - 1

Code Example: http://codepen.io/DevelopIntelligenceBoulder/pen/pgWREp?editors=001

Using the SetCollection

Sets are ordered lists of values which contain no duplicates. Instead of being indexed like an arrays are, sets are accessed using keys. Sets already exist in Java, Ruby, Python, and many other languages. One difference between ES6 Sets and those in other languages is that the order matters in ES6 (not so in many other languages). Here are the crucial Set methods:

Example code - 2

Code Example: http://codepen.io/DevelopIntelligenceBoulder/pen/ZQXLMm?editors=101

Weak Collections, Memory, and Garbage Collections

JavaScript Garbage Collection is a form of memory management whereby objects that are no longer referenced are automatically deleted and their resources are reclaimed.

Map and Set’s references to objects are strongly held and will not allow for garbage collection. This can get expensive if Maps/Sets reference large objects that are no longer needed, such as DOM elements that have already been removed from the DOM.

To remedy this, ES6 also introduces two new weak collections called WeakMap and WeakSet. These collections are ‘weak’ because they allow for objects which are no longer needed to be cleared from memory.

WeakMap

WeakMap is the third new ES6 collection we’ll cover. WeakMaps are similar to normal Maps, albeit with fewer methods and the aforementioned difference with regards to garbage collection.

Example code - 3

Code Examples: http://codepen.io/DevelopIntelligenceBoulder/pen/vLexWe

Use cases

WeakMaps have several popular use cases. They can be used to keep an object’s private data private, and they can also be used to keep track of DOM nodes/objects.

Private data use case

The following example is from JavaScript expert Nicholas C. Zakas:

Example code - 4

Using a WeakMap here simplifies the process of keeping an object’s data private. It is possible to reference the Person object but access to the privateDataWeakMap is disallowed without the specific Person instance.

DOM nodes use case

The Google Polymer project uses WeakMaps in a piece of code called PositionWalker. “PositionWalker keeps track of a position within a DOM subtree, as a current node and an offset within that node.” WeakMap is used to keep track of DOM node edits, removals, and changes:

Example code - 5

WeakSet

WeakSets are Set Collections whose elements can be garbage collected when objects they are referencing are no longer needed. WeakSets do not allow for iteration. Their uses cases are rather limited (for now, at least). Most early adopters say that WeakSets can be used to tag objects without mutating them. ES6-Features.org has an example of adding and deleting elements from a WeakSet in order to keep track of whether or not the objects have been marked:

Example code - 6

Map All Things? Records vs. Collections

Maps and Sets are nifty new collections of key/value pairs. That said, JavaScript objects still can be used as collections in many situations. No need to switch to the new collections unless the situation calls for it.

MDN has has a nice list of questions to determine when to use an object or a keyed collection:

  • Are keys usually unknown until run time, do you need to look them up dynamically?
  • Do all values have the same type, and can be used interchangeably?
  • Do you need keys that aren’t strings?
  • Are key-value pairs often added or removed?
  • Do you have an arbitrary (easily changing) amount of key-value pairs?
  • Is the collection iterated?

New ES6 Collections Yield a More Usable JavaScript

JavaScript collections have previously been quite limited, but this has been remedied with ES6. These new collections will add power and flexibility to the language, as well as simplify the task of JavaScript developers who adopt them.

This article is part of the web development series from Microsoft tech evangelists and DevelopIntelligence on practical JavaScript learning, open source projects, and interoperability best practices including Microsoft Edge browser and the new EdgeHTML rendering engine. DevelopIntelligence offers JavaScript Training and React Training Courses through appendTo, their front-end focused blog and course site.

We encourage you to test across browsers and devices including Microsoft Edge – the default browser for Windows 10 – with free tools on dev.microsoftedge.com, including the EdgeHTML issue tracker, where you can report or search EdgeHTML issues, such as problems with site rendering or standards compliance.Also, visit the Edge blog to stay updated and informed from Microsoft developers and experts.

More:

No Reader comments

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.