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.