JavaScript ES6 for Beginners #12: Sets, WeakSets, Maps and WeakMaps

4 minute read

ES6-card-12

What is a Set?

A Set is an object where we can store unique values of any type.

// create our set
const family = new Set();

// add values to it
family.add("Dad");
console.log(family);
// Set [ "Dad" ]

family.add("Mom");
console.log(family);
// Set [ "Dad", "Mom" ]

family.add("Son");
console.log(family);
// Set [ "Dad", "Mom", "Son" ]

family.add("Dad");
console.log(family);
// Set [ "Dad", "Mom", "Son" ]

As you can see, at the end we tried to add “Dad” again but the Set still remained the same because a Set can only take unique values.

Let’s continue using the same Set and see what methd we can use on it.

family.size;
// 3
family.keys();
// SetIterator {"Dad", "Mom", "Son"}
family.entries();
// SetIterator {"Dad", "Mom", "Son"}
family.values();
// SetIterator {"Dad", "Mom", "Son"}
family.delete("Dad");
// true
family;
// Set [ "Mom", "Son" ]
family.clear;
family;
// Set []

As you can see a Set has a size property and we can delete an item from it or use clear to delete all the items from it.

We can also notice that a Set does not have keys so when we call .keys() we get the same as calling .values() or .entries().

 

Loop over a Set

We have two ways of iterating over a Set: using .next() or using a for of loop.

// using `.next()`
const iterator = family.values();
iterator.next();
// Object { value: "Dad", done: false }
iterator.next();
// Object { value: "Mom", done: false }


// using a `for of` loop
for(const person of family) {
  console.log(person);
}
// Dad
// Mom
// Son

 

Remove duplicates from an array

We can use a Set to remove duplicates from an Array since we know it can only hold unique values.

const myArray = ["dad", "mom", "son", "dad", "mom", "daughter"];

const set = new Set(myArray);
console.log(set);
// Set [ "dad", "mom", "son", "daughter" ]
// transform the `Set` into an Array
const uniqueArray = Array.from(set);
console.log(uniqueArray);
// Array [ "dad", "mom", "son", "daughter" ]

// write the same but in a single line
const uniqueArray = Array.from(new Set(myArray));
// // Array [ "dad", "mom", "son", "daughter" ]

As you can see the new array only contains the unique values from the original array.

 

What is a WeakSet ?

A WeakSet is similar to a Set but it can only contain Objects.

let dad = {name: "Daddy", age: 50};
let mom = {name: "Mummy", age: 45};

const family = new WeakSet([dad,mom]);

for(const person of family){
  console.log(person);
}
// TypeError: family is not iterable

We created our new WeakSet but when we tried to use a for of loop it did not work, we can’t iterate over a WeakSet.

Another big difference that we can see is by trying to use .clear on a WeakSet: nothing will happen because a WeakSet cleans itself up after we delete an element from it.

dad = null;
family;
// WeakSet [ {…}, {…} ]

// wait a few seconds
family;
// WeakSet [ {…} ]

As you can see after a few seconds dad was removed and garbage collected. That happened because the reference to it was lost when we set the value to null.

 

What is a Map ?

A Map is similar to a Set but they have key and value pairs.

const family = new Map();

family.set("Dad", 40);
family.set("Mom", 50);
family.set("Son", 20);

family;
// Map { Dad → 40, Mom → 50, Son → 20 }
family.size;
// 3

family.forEach((key,val) => console.log(val,key));
// Dad 40
// Mom 50
// Son 20

for(const [key,val] of family){
  console.log(key,val);
}
// Dad 40
// Mom 50
// Son 20

If you remember, we could iterate over a Set only with a for of loop while we can iterate over a Map with both a for of and a forEach loop.

 

What is a WeakMap ?

A WeakMap is a collection of key/value pairs and similarly to a WeakSet, even in a WeakMap the keys are weakly referenced, which means that when the reference is lost the value will be removed from the WeakMap and garbage collected.

A WeakMap is not enumerable therefore we cannot loop over it.

let dad = { name: "Daddy" };
let mom = { name: "Mommy" };

const myMap = new Map();
const myWeakMap = new WeakMap();

myMap.set(dad);
myWeakMap.set(mom);

dad = null;
mom = null;

myMap;
// Map(1) 
myWeakMap;
// WeakMap {}

As you can see mom was garbage collected after we set the its value to null whilst dad still remains inside our Map.


 

This was the last part of my ES6 for beginners course, check out the rest of them here.

You can also read this articles on medium, on my profile.

I will soon start posting a new tutorial on the new features introduce post ES6 so stay tuned.

Thank you for reading.

Leave a Comment