A Map retains its keys and values while reachable. A cache that never evicts can therefore retain every record it has seen. Removing an item from the application’s main list does not remove it from a separate cache.
WeakMap is useful for metadata keyed by objects when the metadata should not keep those objects alive on its own. It does not provide size or enumeration, and you cannot write a deterministic test for the exact moment a key is garbage-collected. Weak references are not a replacement for explicit cleanup of listeners, timers or resources.
For primitive-key caches, choose an explicit eviction policy. The exercise implements a small oldest-insertion cache, not an LRU cache: reading a key does not change its age, while rewriting it will. Naming that distinction prevents a misleading API.
The pool retains result values until completion. Bounded active calls do not make its total memory constant. If you need a streaming result API, design a separate ordering and buffering contract rather than claiming this array-returning API already streams.
Predict, run, and explain
Write the output and trace the important state changes before checking it. Then run the program. Each editor is independent. Async examples end with main() so this editor waits for their work.
const metadata = new WeakMap();
const item = { id: "a" };
metadata.set(item, { seen: true });
console.log(metadata.get(item).seen);
const cache = new Map([
["a", 1],
["b", 2]
]);
cache.delete("a");
console.log(cache.size);Check your prediction
true
1 Bound retained entries with an observable policy
A cache holds references while its entries remain reachable. Removing a value from another application list does not release a separate cache entry. Bound the cache according to a stated eviction rule and test that rule through keys and lookups.
Oldest insertion and least recently used are different policies. A plain Map get does not change insertion order. WeakMap avoids retaining object keys by itself, but provides neither enumeration nor a deterministic moment at which you can assert collection occurred.
const cache = new Map([
["a", 1],
["b", 2]
]);
cache.get("a");
cache.set("c", 3);
cache.delete(cache.keys().next().value);
console.log([...cache.keys()].join(","));Check your prediction
b,c Reading a did not refresh its insertion age. This is a valid oldest-insertion eviction example, but it would fail a true LRU contract.
const cache = new Map([
["a", 1],
["b", 2]
]);
cache.delete("a");
cache.set("a", 10);
console.log([...cache.keys()].join(","));
console.log(cache.get("a"));Check your prediction
b,a
10 Delete followed by set moves a rewritten key to the newest position. Merely overwriting an existing key does not do that, so the two operations encode a deliberate policy.
Try the rule on new inputs
Test capacity one, repeated reads, repeated writes and insertion after eviction. For WeakMap, test association while a key is reachable; do not make garbage-collection timing part of an expected output.
Your turn
Memory & Lifetime: practise
Implement remember(key, value) around a Map with capacity 2. Rewriting a key moves it to newest insertion; when over capacity remove the oldest key. Insert a, b, c and print b,c.
// Map iteration order is insertion order; delete a rewritten key before setting it.Hint 1: the idea
Explicit eviction bounds retained entries.
Hint 2: a first step
The oldest key is cache.keys().next().value.
Show one solution
const cache = new Map();
function remember(key, value) {
cache.delete(key);
cache.set(key, value);
if (cache.size > 2) {
cache.delete(cache.keys().next().value);
}
}
remember("a", 1);
remember("b", 2);
remember("c", 3);
console.log([...cache.keys()].join(","));b,cExplain why the implementation meets the stated contract. Which part is enforced by the language or checker, and which part needs behavioral evidence?
Change it and test it
Test rewriting b and verify its insertion age changes. Explain why a get does not make this LRU. For WeakMap, test association while a key is reachable, but do not assert garbage collection happens after a timeout.
Completion is saved in this browser only. It does not measure mastery.