ES6 of the Week
This Week's Episode:
maps and sets
Maps and Sets
-
In JavaScript, objects wear many hats:
- We use objects as HashMaps or dictionaries, as well as instances of classes
- Sometimes, if we know we want to store data in a certain way, it may be safer and more efficient to use a different data structure than the JS engine's implementation of objects
- Enter: Maps and Sets
Sets
- Sets are a collection of unique values of any type
- This includes object references
- Items in a Set will be iterated through in the order they were inserted
- Because each item in the set is unique, you can check their equality at a high level (i.e. if you compare an item in a Set that references a specific object in memory, it will evaluate as equal to another pointer to that same object in memory
On your mark, get set...
let _set = new Set(); // n.b. set is a reserved word, so I'm calling my variable _set
// Set.prototype.add
_set.add("string").add(42);
// store object references
let obj = { a : 1 };
_set.add(obj);
// Set.prototype.size
_set.size // => 3
_set.add(42) // no repeats
_set.size // => 3
// Set.prototype.has
_set.has("string") // true
_set.has(obj) // true, wowzers!
_set.has(21) // false
// Iterate using for...of
for (let item of _set) console.log(item); // logs in insertion order
// Set.prototype.delete and Set.prototype.clear
_set.delete("string"); // remove a single item
_set.clear(); // wipe the set clean
Arrays
Could have duplicates
Actually an object
Iterate with for loop
Sets
Unique values
No baggage
Iterate with for...of
Maps
- A key-value map
- Keys can contain object references, functions, or whatever
- No need to worry about Object.hasOwnProperty when iterating
- Has handy methods that make it easy to get the size, or iterate over either the values or keys
Objects
Has a prototype (default key)
Keys are strings or symbols
Cannot get size easily
Maps
No prototype
Keys are any type
Can get size easily
Follow the Map!
let _map = new Map(); // now I'm just being consistent ;)
// Map.prototype.set
_map.set('a', 1);
_map.set('b', 2);
let objKey = { 'c' : 3 };
_map.set(objKey, 4);
// Map.prototype.get
_map.get('a'); // => 1
_map.get(objKey); // => 4
// Map.prototype.size - much easier than using Object.hasOwnProperty!
_map.size; // => 3
// Iterate over keys using Map.prototype.keys
for (let key of _map.keys()) console.log(key);
// Iterate over values using Map.prototype.values
for (let value of _map.values()) console.log(value);
WeakSet and WeakMap
- Have a subset of the same Set/Map methods/properties (but not all)
- WS: Add, has, delete
- WM: Get, set, has delete
- WeakSets can only contain objects, and the keys of WeakMaps can only be objects
- Objects in WeakSets and WeakMaps are weakly held, meaning that if no other reference to them exists, they will be garbage collected
- Advantageous for freeing up memory
- This also means they are not enumerable (not iterable)
WeakMap example
let _counter = new WeakMap();
let _action = new WeakMap();
class Countdown {
constructor(counter, action) {
_counter.set(this, counter);
_action.set(this, action);
}
dec() {
let counter = _counter.get(this);
if (counter < 1) return;
counter--;
_counter.set(this, counter);
if (counter === 0) {
_action.get(this)();
}
}
}
// http://www.2ality.com/2015/01/es6-maps-sets.html
Use Cases
- Set
- Any collection of unique values
- Map
- Quite versatile
- Dictionary-like collections, especially those that will be iterated over
- WeakSet
- 'branding' your classes?
- WeakMap
- storing metadata for an object
- prevent memory leaks in the DOM
- http://stackoverflow.com/questions/29413222/what-are-the-actual-uses-of-es6-weakmap
Resources
- ES6: http://es6-features.org/
- Wiki: https://en.wikipedia.org/wiki/Object_(computer_science)
-
Mozilla docs:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
-
Blogs & StackOverflow
- http://bjorn.tipling.com/maps-sets-and-iterators-in-javascript
- http://www.sitepoint.com/preparing-ecmascript-6-set-weakset/
- http://stackoverflow.com/questions/29413222/what-are-the-actual-uses-of-es6-weakmap
- https://esdiscuss.org/topic/actual-weakset-use-cases
- http://www.2ality.com/2015/01/es6-maps-sets.html
ES6 of the Week - 5
By Tom Kelly
ES6 of the Week - 5
Maps and Sets
- 1,607