Languages like Java and C# expose a HashSet type for unique elements and fast membership tests. JavaScript does not spell HashSet in the standard library, but hashset javascript searches almost always want the same behavior: unique values, has in average sublinear time (implementations may use hash tables internally—see MDN Set), and predictable iteration. The built-in answer is Set. For javascript hash set style key → value storage with unique keys, use Map instead.
This guide shows Set construction, add deduplication, iteration, delete / has, object identity, array dedupe, and a tiny Map contrast.
Tested on: Node.js v20.18.2. A short note after each snippet describes what you should see in the console.
Quick reference
Use this table when you are translating Java HashSet / C# HashSet mental models into JavaScript: Set for unique values, Map for unique keys with payloads, [...new Set(arr)] to dedupe arrays.
| Goal | Type |
|---|---|
Unique values, membership has |
Set |
| Unique keys with associated values | Map |
| Dedupe array | [...new Set(arr)] |
1. Create a Set (hashset in javascript)
Constructing from an iterable seeds the set in one step; size reflects unique membership.
const theSet = new Set([1, 2, 3, 4, 5]);
console.log(theSet);You should see one line like: Set(5) { 1, 2, 3, 4, 5 }.
2. add ignores duplicates (js hashset behavior)
Repeated add with the same value is a no-op; only the first successful insertion affects order and size.
const mySet = new Set();
mySet.add("one");
mySet.add("one");
mySet.add("two");
mySet.add("three");
mySet.add("four");
mySet.add("five");
console.log(mySet);You should see one line like: Set(5) { 'one', 'two', 'three', 'four', 'five' }.
3. Iterate in insertion order with forEach
forEach visits each member once; callback order matches insertion order, not sort order.
const mySet = new Set(["one", "two", "three", "four", "five"]);
mySet.forEach(function (value) {
console.log(value);
});You should see 5 lines of output, starting with one and ending with five.
4. delete and has
delete removes by value; has answers membership without mutating the set.
const theSet = new Set(["one", "two", "three", "four", "five"]);
console.log(theSet);
theSet.delete("five");
console.log(theSet);
console.log(theSet.has("four"));You should see 3 lines: Set(5) { 'one', 'two', 'three', 'four', 'five' }, then Set(4) { 'one', 'two', 'three', 'four' }, then true.
5. Objects are compared by reference (hashset in js gotcha)
Primitives dedupe by value; objects dedupe only when the same reference is added twice.
Two different object literals are not equal under ===, so Set keeps both unless you delete the same reference you added.
const theSet = new Set();
theSet
.add({ user: "jack", has: false })
.add({ user: "Ox", has: true })
.add({ user: "femi", has: false });
theSet.forEach((data) => {
if (data.has === true) theSet.delete(data);
});
console.log(theSet);You should see one line like: Set(2) { { user: 'jack', has: false }, { user: 'femi', has: false } }.
For “unique by id” or “unique by serialized shape,” use a Map keyed by id/string, or normalize before add.
6. Dedupe an array; NaN counts once
Spreading a Set built from an array is the idiomatic one-liner dedupe; NaN follows SameValueZero rules.
console.log([...new Set([1, 2, 2, 3])]);
console.log(new Set([NaN, NaN]).size);You should see 2 lines: [ 1, 2, 3 ], then 1.
7. When people mean hash set javascript but need Map
Set is “bag of unique values.” When each record has a key and a payload, Map matches the mental model better.
const m = new Map([
["a", 1],
["b", 2],
]);
m.set("a", 3);
console.log(m.size);
console.log([...m.keys()]);You should see 2 lines: 2, then [ 'a', 'b' ].
Summary
The main takeaway: Set for unique values and fast has, Map for unique keys with values, [...new Set(arr)] for array dedupe—mind object identity and NaN.
Setstores each value at most once; iteration follows insertion order.add/has/delete/sizecover the usual hash-set operations; objects use reference identity.- Spread
new Set(arr)dedupes primitives;NaNis handled once under SameValueZero. - Use
Mapwhen each entry is a key paired with a value.
References
MDN and a Stack Overflow reference for HashSet-style collections in JavaScript.
