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.

javascript

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.

javascript

// 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.

javascript

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) - returns true if 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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.
  • size is a property that returns the count of elements.
  • add(), has(), delete(), and clear() are the core methods.
  • Use for...of or forEach() to iterate over values.
  • Convert a Set to an array with [...set] or Array.from(set).
  • Sets do not support index-based access.
  • A WeakSet holds weak references to objects and is not iterable.