Set
A Set is a built-in JavaScript object that stores a collection of unique values. Unlike arrays, a Set automatically removes duplicate entries - each value can only appear once.
Sets can hold any type of value: numbers, strings, objects, or even other Sets. They are especially useful when you need to work with a list of items and want to guarantee there are no duplicates.
const mySet = new Set([1, 2, 3, 2, 1]);
console.log(mySet); // Set(3) { 1, 2, 3 }
// Duplicates are automatically removed
You create a Set using the new Set() constructor. You can pass an iterable (like an array) to pre-populate it, or create an empty Set and add values later.
// Empty Set
const emptySet = new Set();
emptySet.add(10);
emptySet.add(20);
console.log(emptySet); // Set(2) { 10, 20 }
// Set from an array
const numSet = new Set([1, 2, 3]);
console.log(numSet); // Set(3) { 1, 2, 3 }
// Duplicate values are ignored
const colors = new Set(["red", "blue", "red", "green"]);
console.log(colors); // Set(3) { 'red', 'blue', 'green' }
A Set maintains insertion order. This means values are stored and iterated in the order they were added - first in, first out.
This is different from a plain object where property order is not always guaranteed. With a Set, you can rely on consistent ordering.
const mySet = new Set();
mySet.add("banana");
mySet.add("apple");
mySet.add("cherry");
// Values come out in insertion order
for (const fruit of mySet) {
console.log(fruit);
}
// banana
// apple
// cherry
JavaScript Set comes with several built-in methods and one property to help you work with its contents. Here is a quick overview:
size- returns the number of elements (property, not a method).add(value)- adds a new value to the Set.has(value)- returnstrueif the value exists.delete(value)- removes a specific value.clear()- removes all values from the Set.forEach(callback)- iterates over each value.values()- returns an iterator of all values.
The sections below cover each of these in detail with examples.
size is a property (not a function) that returns the number of unique values in the Set. You access it without parentheses.
This is similar to array.length in arrays. The count updates automatically when you add or remove values.
const mySet = new Set([10, 20, 30, 20]);
console.log(mySet.size); // 3 (not 4, because 20 is a duplicate)
mySet.add(40);
console.log(mySet.size); // 4
mySet.delete(10);
console.log(mySet.size); // 3
The has() method checks whether a specific value exists in the Set. It returns true if the value is found, and false if it is not.
Checking membership with has() on a Set is faster than using indexOf() or includes() on a large array, because Sets use a hash-based lookup internally.
const fruits = new Set(["apple", "banana", "cherry"]);
console.log(fruits.has("banana")); // true
console.log(fruits.has("mango")); // false
The delete() method removes a specific value from the Set. It returns true if the value was found and removed, or false if the value did not exist.
const nums = new Set([1, 2, 3, 4]);
console.log(nums.delete(3)); // true - 3 was removed
console.log(nums.delete(9)); // false - 9 was not in the Set
console.log(nums); // Set(3) { 1, 2, 4 }
Two more commonly used Set methods are add() and clear().
add(value) inserts a new value into the Set. If the value already exists, it is silently ignored - no error is thrown. clear() removes all values from the Set at once, leaving it empty.
const mySet = new Set();
// add()
mySet.add("a");
mySet.add("b");
mySet.add("a"); // duplicate, ignored
console.log(mySet); // Set(2) { 'a', 'b' }
// clear()
mySet.clear();
console.log(mySet); // Set(0) {}
console.log(mySet.size); // 0
The add() method returns the Set itself, so you can chain multiple add() calls together: mySet.add(1).add(2).add(3).
Sets do not support indexes. Unlike arrays, you cannot access a Set element by its position using bracket notation like mySet[0].
This is by design - Sets are meant for checking membership and ensuring uniqueness, not for positional access. To get a specific element, you either iterate the Set or convert it to an array first.
const mySet = new Set([10, 20, 30]);
// This does NOT work - Sets have no index
console.log(mySet[0]); // undefined
// Convert to array first if you need index access
const arr = [...mySet];
console.log(arr[0]); // 10
console.log(arr[1]); // 20
The for...of loop is the simplest and most common way to iterate over all values in a Set. Values are visited in insertion order.
const languages = new Set(["JavaScript", "Python", "Java"]);
for (const lang of languages) {
console.log(lang);
}
// JavaScript
// Python
// Java
You can also call set.values() to get an iterator and loop over it in the same way. Both approaches produce identical results.
const nums = new Set([5, 10, 15]);
for (const val of nums.values()) {
console.log(val);
}
// 5
// 10
// 15
There are two easy ways to convert a Set into a regular array: the spread operator ([...set]) and Array.from(). Both give the same result.
Converting to an array is useful when you need array methods like map(), filter(), or reduce() that are not available on a Set.
const mySet = new Set([1, 2, 3, 4]);
// Using spread operator
const arr1 = [...mySet];
console.log(arr1); // [1, 2, 3, 4]
// Using Array.from()
const arr2 = Array.from(mySet);
console.log(arr2); // [1, 2, 3, 4]
// Practical use - remove duplicates from an array
const withDups = [1, 2, 2, 3, 3, 4];
const unique = [...new Set(withDups)];
console.log(unique); // [1, 2, 3, 4]
The forEach() method executes a callback function once for each value in the Set, in insertion order. The callback receives the value as its first argument.
Note that the callback receives the value as both the first and second argument - this is for consistency with the Map.forEach() API. The third argument is the Set itself.
const colors = new Set(["red", "green", "blue"]);
colors.forEach(function(value) {
console.log(value);
});
// red
// green
// blue
// Using arrow function
colors.forEach(color => console.log(color.toUpperCase()));
// RED
// GREEN
// BLUE
A WeakSet is similar to a Set, but with two key differences: it can only store objects (not primitive values), and it holds weak references to those objects.
"Weak reference" means that if an object stored in a WeakSet has no other references pointing to it, JavaScript's garbage collector can remove it from memory automatically. WeakSets are not iterable and have no size property.
const ws = new WeakSet();
let obj1 = { name: "Alice" };
let obj2 = { name: "Bob" };
ws.add(obj1);
ws.add(obj2);
console.log(ws.has(obj1)); // true
obj1 = null; // obj1 can now be garbage collected
// WeakSet only supports: add(), has(), delete()
// ws.size and for...of are NOT available
WeakSets are useful for tagging or tracking objects (such as DOM nodes) without preventing them from being garbage collected when no longer needed.
Here is a quick recap of what you have learned about JavaScript Sets:
- A Set stores unique values - no duplicates allowed.
- Sets maintain insertion order.
sizeis a property that returns the count of elements.add(),has(),delete(), andclear()are the core methods.- Use
for...oforforEach()to iterate over values. - Convert a Set to an array with
[...set]orArray.from(set). - Sets do not support index-based access.
- A WeakSet holds weak references to objects and is not iterable.