The recurring pattern "read a key, create a default if missing, then use it" takes three calls and looks the key up up to three times:
if (!map.has(key)) map.set(key, []);
map.get(key).push(value);
The "upsert" methods do it in one call that returns the value:
map.getOrInsert(key, value)returns the existing value if the key is present; otherwise it storesvalueand returns it.map.getOrInsertComputed(key, callback)does the same but callscallback(key)only when the key is missing and stores the result. Use it when the default is a fresh object ([],new Set()) or costly to build.
The distinction matters because arguments are evaluated first. map.getOrInsert(key, []) allocates a new array on every call, even when the key exists and the array is thrown away; getOrInsertComputed(key, () => []) allocates only on a miss.
Details from the spec:
- Keys are compared like
Map.prototype.setdoes, with-0canonicalised to+0. getOrInsertComputedthrows aTypeErrorifcallbackis not callable. Ifcallbackitself adds that key to the map, the spec's re-check overwrites the entry with the callback's return value.WeakMaphas both methods, with the sameCanBeHeldWeaklykey rule asset.
Availability (checked, not assumed). The TC39 upsert proposal is at Stage 4, and getOrInsert / getOrInsertComputed are in the living ECMAScript specification. MDN lists them as Baseline 2026 (newly available since February 2026). In this repo's runs, Node 24.19 does not have them (typeof is undefined) and Node 26.7 does. So feature-detect, or use a small helper for older runtimes, as below. Which numbered ECMAScript edition first includes them is ❓ not verified here.