Concept
The beginner framing: Map and Set are built-in data structures added in ES2015 specifically to fix real limitations of using plain objects and arrays as makeshift key-value stores and unique collections.
The precise mental model: a plain object was never actually designed to be a general-purpose map, it's an object with (usually) a prototype, string/symbol-only keys, and no built-in size tracking. Map fixes all three: any value can be a key (including objects and functions, not just strings), no prototype pollution risk (no inherited properties like toString silently showing up in for...in), and a real .size property instead of manually computing Object.keys(obj).length.
const userRoles = new Map();
const user1 = { name: "Ada" };
const user2 = { name: "Grace" };
userRoles.set(user1, "admin"); // the OBJECT itself is the key, impossible with a plain object
userRoles.set(user2, "editor");
console.log(userRoles.get(user1)); // "admin"
console.log(userRoles.size); // 2
for (const [user, role] of userRoles) {
console.log(user.name, role); // insertion order is GUARANTEED, unlike some object key orderings
}Set: guaranteed-unique values
const uniqueIds = new Set([1, 2, 2, 3, 3, 3]);
console.log(uniqueIds.size); // 3, duplicates automatically collapsed
console.log(uniqueIds.has(2)); // true
const uniqueArray = [...new Set([1, 2, 2, 3])]; // [1, 2, 3], the classic dedup one-linerWeakMap/WeakSet: keys that don't prevent garbage collection
This is the feature that makes the "Weak" variants genuinely different, not just a naming convention, a regular Map's keys are strong references, meaning the map itself keeps every key object alive (reachable) for as long as the map exists, even if nothing else in the program references that key anymore. A WeakMap's keys are weak references, they do not count toward reachability (see Garbage Collection), so if a key object becomes otherwise unreachable, it (and its associated value) can be collected, automatically, with the entry silently disappearing from the map.
let el = document.getElementById("widget");
const privateData = new WeakMap();
privateData.set(el, { clickCount: 0 }); // associate private data with this specific DOM node
el = null; // the ONLY other reference to this element is gone (assume it's also removed from the DOM)
// The WeakMap's key reference does NOT keep it alive, the element AND its
// associated privateData entry become eligible for garbage collection together.This is exactly why WeakMap is the standard tool for attaching metadata to objects (especially DOM nodes) without creating a memory leak, a regular Map used the same way would keep every DOM node alive forever, even after it's removed from the page.
The tradeoff: WeakMap/WeakSet are deliberately not iterable, no .size, no for...of, no .keys(). This isn't an oversight; it's required, because the collection's contents can change at any moment as the garbage collector runs (an entry could silently vanish between two lines of your code), allowing iteration would expose non-deterministic, GC-timing-dependent behavior to your program.
Typed arrays: binary data, done right
const buffer = new ArrayBuffer(8); // 8 raw bytes of memory
const view = new Int32Array(buffer); // interpret those 8 bytes as two 32-bit integers
view[0] = 42;
view[1] = 100;
console.log(view); // Int32Array(2) [42, 100]