Set.prototype.entries()
Returns an iterator yielding a [value, value] pair for each element, mirroring the Map API.
entries()- Added in JavaScript ES2015
Return value
Set IteratorA new iterable iterator object that yields a [value, value] array for each element, in insertion order.
Errors
Throws a TypeError if called on a value that is not a real Set instance.
entries() yields [value, value] — the same value twice, as a two-element array. A Set has no keys, but the method exists so that the iteration API matches Map's. Each entry's "key" slot simply repeats the value.
When it is the right call
Almost never for reading your own collection: values() or plain for...of give you the value without the wrapper array, and allocating a pair per element to immediately discard half of it is waste. Reach for entries() when something else demands entry-shaped input — Object.fromEntries(), a Map constructor, or generic code written against "any keyed collection" that calls entries() on whatever it is handed. In that last case a Set can be passed where a Map was expected and the code keeps working.
Same iterator rules
Like every set iterator it is single-use, lazy, and live: drain it once and it stays done, and additions or deletions made ahead of the cursor during iteration are reflected. The pair arrays themselves are freshly allocated on each next(), so mutating one has no effect on the collection.
Example
When to use it
- Feed a collection into Object.fromEntries() to build a self-keyed lookup object
- Pass a Set to helper code written against the Map iteration protocol
- Convert a collection of strings into a Map whose keys and values match
- Inspect that entry pairs really do hold the same value on both sides
Frequently asked questions
Why does Set entries() return the same value twice?
Because a Set has no keys, and the pair shape exists only to keep the iteration API identical to Map's. The key slot is filled with the value so entry-consuming code works unchanged.
Should I use entries() to loop over a Set?
No — use for...of or values(), which give the value directly without allocating a pair array per element. Save entries() for APIs that specifically want [key, value] input, like Object.fromEntries().
Does entries() give me the index of each element?
No, there are no indexes in a Set; the first slot is the value again, not a position. Use for...of with an external counter, or spread into an array and use entries() on that array instead.
More examples
Building a self-keyed lookup object
Because each entry is a pair of the same value, fromEntries produces an object whose keys equal their values — the usual shape for a string enum. The manual map version below shows exactly what entries() was doing.
const roles = new Set(["admin", "editor", "viewer"]);
const ROLE = Object.fromEntries(roles.entries());
console.log(ROLE);
console.log(ROLE.editor);
// Same idea, made explicit
console.log(Object.fromEntries([...roles].map((r) => [r, r])));Why entries() is usually the wrong choice
Both loops print the same three values, but the first allocates a throwaway array per element and needs a hole in the destructuring pattern. Writing into a yielded pair changes only that array — the collection is untouched.
const s = new Set([10, 20, 30]);
for (const [, value] of s.entries()) console.log("entries:", value);
for (const value of s) console.log("for...of:", value);
// The pair is a fresh array each time, not a view
const [pair] = [...s.entries()];
pair[0] = 999;
console.log(pair, [...s]);Duck-typing against the Map protocol
The same helper accepts both types because a Set answers entries() too. For the Map the keys and values differ; for the Set each pair repeats its value, giving "a=a" and "b=b".
function describe(collection) {
const out = [];
for (const [k, v] of collection.entries()) out.push(`${k}=${v}`);
return out;
}
console.log(describe(new Map([["a", 1], ["b", 2]])));
console.log(describe(new Set(["a", "b"])));
Discussion