Objects are pretty cool I guess
But we can do better!
Map
A collection of keyed data items. Keys can be any type.
new Map() // creates the map
map.set(key, value) // stores the value against the key
map.get(key) // returns the value associated with the key
map.has(key) // true if the key exists, otherwise false
map.delete(key) // removes the value by the key
map.clear() // clears the map
map.size // returns the current element count
Keys are compared using ===, except NaN will equal NaN.
const map = new Map();
map.set('123', 'string keys are cool');
map.set(123, 'number keys are cooler');
map.set(true, 'too true!');
// A regular Object would convert keys to strings,
// so these two would not be different:
console.log(map.get('123')); // 'string keys are cool'
console.log(map.get(123)); // 'number keys are cooler'
console.log(map.size); // 3
Map example one
const ariela = {name: 'Ariela'};
const takayoshi = {name: 'Takayoshi'};
const ages = new Map();
// Note that map methods return themselves, so you can chain
ages.set(ariela, 53)
.set(takayoshi, 30);
console.log(ages.get(ariela)); // 53
Map example two
const map = new Map([
['name', 'Takayoshi'],
['age', 30]
]);
const map = new Map(Object.entries({
name: 'Takayoshi',
age: 30
}));
Map from Object
const menu = new Map([
['avo poached eggs', 13],
['grilled grapefruit', 6],
['coconut chia pot', 7]
]);
for (let menuItem of menu.keys()) {
console.log(menuItem); // avo poached eggs, grilled...
}
for (let amount of menu.values()) {
console.log(amount); // 13, 6, 7
}
for (let entry of menu) { // Same as of menu.entries()
console.log(entry); // avo poached eggs,13...
}
menu.forEach((value, key, map) => {
console.log(`${key}: ${value}`); // avo poached eggs: 13 etc
});
Map iteration
Iteration order is retained 🎉
Set
A collection of values where each value may occur only once.
new Set(iterable) // creates the set
set.add(value) // adds a value
set.delete(value) // removes value, returns true if value existed
set.has(value) // returns true if the value exists in the set
set.clear() // removes everything from the set
set.size // returns the current element count
const visits = new Set();
const ariela = {name: 'Ariela'};
const takayoshi = {name: 'Takayoshi'};
const lana = {name: 'Lana'};
// Visits, some users come multiple times
visits.add(ariela);
visits.add(takayoshi);
visits.add(lana);
visits.add(ariela);
visits.add(lana);
console.log(visits.size); // 3 - only unique values
for (let user of visits) {
console.log(user.name); // In order: Ariela, Takayoshi, Lana
}
Set example
const morningTea = new Set(['croissant', 'macaron', 'financier']);
for (let value of morningTea) {
console.log(value);
}
// Note the weirdness here
morningTea.forEach((value, valueAgain, morningTea) => {
console.log(value);
});
// Both print croissant, macaron, financier
Set iteration
GC refresher
- Memory management in JavaScript is performed automatically and invisibly to us
- Anything no longer "reachable" is cleaned up
- "Reachable" values are those that are accessible or usable somehow
let ariela = {name: 'Ariela'};
// The object can be accessed, ariela is the reference to it
// Let's overwrite the reference..
ariela = null;
// The object will be removed from memory
GC example
GC continued
- Usually, properties of an object or elements of an array or another data structure are considered reachable while that data structure is in memory
- If we use an object in a Map, it's kept in memory even if there are no more references to it.
let takayoshi = {name: 'Takayoshi'};
const secrets = new Map();
secrets.set(takayoshi, 'Likes The Good Place');
takayoshi = null; // Overwrite the reference
// takayoshi is stored inside the map - we can
// still get it using secrets.keys()
WeakMap
A Map that does not prevent object removal from memory.
let lana = {name: 'Lana'};
const weakAgeMap = new WeakMap();
// Keys must be Objects
weakAgeMap.set(lana, 8);
lana = null; // Overwrite the reference
// There are no references except WeakMap, so the Lana object is
// removed both from the memory and from weakAgeMap automatically
WeakMap does not support methods keys(), values(), entries(), we can not iterate over it.
weakMap.get(key)
weakMap.set(key, value)
weakMap.delete(key, value)
weakMap.has(key)
WeakMap methods
WeakSet
A Set (of objects) that only exist while they are reachable elsewhere.
Like Set, it supports add, has and delete, but not size or keys(). You can't iterate over a WeakSet.
WeakSet example
const messages = [
{text: 'How do you like your eggs?', from: 'Takayoshi'},
{text: 'Scrambled', from: 'Ariela'},
{text: 'Let\'s do brunch!', from: 'Lana'}
];
// Fill it with array elements (3 items)
const unreadSet = new WeakSet(messages);
// We can use unreadSet to see whether a message is unread
console.log(unreadSet.has(messages[1])); // true
// Remove it from the set after reading
unreadSet.delete(messages[1]); // true
// If we remove an item from our message list, the set is
// cleaned up automatically
messages.shift();
// No need to clean unreadSet, it now has 2 items
// unfortunately, there's no method to get the exact count
// of items, so can't show it
WeakMap & WeakSet
The absence of iterations and inability to get all the current content seem inconvenient, but their main job is to be additional storage of data for objects which are stored / managed elsewhere.
Map and Set
By Helen Durrant
Map and Set
Let's talk about Map and Set
- 382