One more edge case: cache[id] coerces keys to strings, so cache[1] and cache["1"] end up as the same entry, which rather defeats the point of using Map.
if (cache[id]) trips me up the most, since 0 or "" gets treated like a miss and you end up rebuilding. A Map fixes that with cache.has(id), so falsy values still count as cached and you can get them right after.
One more weirdness: by doing cache[id] = user you can accidentally stomp on real Map properties (try id = "size" and now cache. size is an object), which is a fun way to create a “works until it doesn’t” bug.
Yeah, that’s the sort of bug that only shows up in prod at 4:55pm on a Friday. If you really want a plain key/value cache, new Map() (or Object. create(null) if you’re being old-school) saves you from tripping over size/constructor nonsense.