← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Map, Set, WeakMap & WeakSet

javascript ES2015 Intermediate
debt(d5/e3/b3/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). ESLint and TypeScript can detect some patterns (Object used as map, Array.indexOf for membership), but detection is not automatic or comprehensive. The code_pattern hints indicate these are detectable via linting rules, but require explicit rule configuration and don't catch all misuses (e.g., subtle prototype pollution edge cases only emerge in code review or runtime testing).

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix states the solution is straightforward: replace Object with Map for non-string keys, or array with Set for membership checks. These are typically single-file, single-component refactors within a data structure usage, not cross-cutting changes. No architectural rework required.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Map/Set choices are typically confined to the component or module where they're used. While applies_to includes both web and cli contexts, this choice doesn't impose reach across the system or gravitational pull on future architecture. The decision affects only the data structure layer in isolated components, not global patterns or shared abstractions.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception field directly identifies the trap: developers believe plain objects are always fine as dictionaries, unaware of prototype property surprises (constructor, toString) and that object keys coerce to strings. This is a documented gotcha that most JavaScript developers eventually learn through experience or code review. Common mistakes confirm iteration gotchas (for...in vs for...of) add cognitive friction beyond the initial data structure choice.

About DEBT scoring →

Also Known As

ES6 Map ES6 Set WeakMap WeakSet

TL;DR

ES6 collections that improve on plain objects for key-value storage (Map), unique value lists (Set), and memory-safe object associations (WeakMap, WeakSet).

Explanation

Map is like an object but allows any type as key, maintains insertion order, and has built-in size. Set stores unique values of any type. WeakMap and WeakSet hold weak references — keys (WeakMap) or values (WeakSet) are garbage collected when no other references exist. Map vs object: Maps are better for frequent add/delete operations and non-string keys. Set vs array: Set membership is O(1); array includes() is O(n). WeakMap is ideal for private data and caches keyed by object instances.

Common Misconception

Plain objects are always fine as dictionaries — objects have prototype properties that can cause surprises with key names like 'constructor' or 'toString'; Map is safer for dynamic keys.

Why It Matters

Set.has() is O(1) vs Array.includes() O(n) — for deduplication and membership checks over large collections, Set is dramatically faster.

Common Mistakes

  • Using an object instead of Map for a dictionary with non-string keys — object keys are always coerced to strings.
  • Iterating a Map with for...in — use for...of or Map.forEach(); for...in is for object prototype chains.
  • Not using Set for deduplication — [...new Set(array)] is the cleanest deduplication pattern.
  • Using Map where a plain object suffices for static, known string keys — Map has overhead for simple static configs.

Code Examples

✗ Vulnerable
// Array for deduplication — O(n²):
const unique = arr.filter((v, i) => arr.indexOf(v) === i); // indexOf is O(n)

// Object as dictionary with non-string keys:
const map = {};
map[objectKey] = value; // key coerced to '[object Object]' — all map to same slot
✓ Fixed
// Set for O(n) deduplication:
const unique = [...new Set(arr)];

// Map for any-type keys:
const cache = new Map();
cache.set(objectInstance, computedValue);
cache.get(objectInstance); // Uses object identity, not string coercion

// WeakMap for private data (GC-safe):
const _private = new WeakMap();
class User {
    constructor(name) { _private.set(this, { name }); }
    getName() { return _private.get(this).name; }
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 31
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 2 pings T 0 pings F 3 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S
No pings yesterday
Amazonbot 9 Perplexity 4 Unknown AI 3 Ahrefs 2 Google 2 ChatGPT 2 SEMrush 2 Majestic 1
crawler 22 crawler_json 2 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use Map instead of plain objects when keys are non-strings or insertion order matters for iteration; use Set for unique value collections instead of arrays with indexOf checks
📦 Applies To
javascript ES2015 web cli
🔗 Prerequisites
🔍 Detection Hints
Object used as map with non-string keys; array with indexOf check for membership when Set would be O(1); WeakMap not used for object metadata
Auto-detectable: ✗ No eslint typescript
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✓ Auto-fixable Fix: Low Context: Function

✓ schema.org compliant