Really appreciate this - genuinely useful corrections, adding all four to the post:
Good catch on -0/+0 - I only mentioned the NaN side of SameValueZero, missed that the zeros collapse the other direction.
The WeakMap point is the one I should've led with, actually. "Cache by object reference" without mentioning the strong-reference leak risk is incomplete advice.
The JSON one is brutal in practice because it fails silently - no error, just an empty payload. Worth its own callout.
Object.create(null) is a nice addition for the "don't need full Map, just want no prototype" case.
Updated the article with all of these. Thanks for reading closely enough to catch this.
Clear write-up, and the SameValueZero note is the right one to flag. Three things worth adding, since they all bite in the exact cases you recommend these for:
SameValueZero also collapses -0 and +0. new Set([0, -0]).size is 1, and map.set(0, 'a').set(-0, 'b') leaves you with one entry. So it is not only NaN that behaves differently from ===; the zeros go the other way.
"Caching by object reference" with a Map is the one recommendation that can leak. A Map holds a strong reference to its keys, so a cache keyed by DOM nodes or by objects keeps them alive forever, even after the rest of the app has dropped them. WeakMap (and WeakSet) exist for exactly that: the entry disappears when the key becomes unreachable. The trade is that a WeakMap has no .size and is not iterable, which is the point.
Map and Set do not survive JSON. JSON.stringify(new Map([['a', 1]])) gives "{}", and so does a Set. People swap an Object for a Map, hit their API layer, and the payload silently empties. [...map] and [...set] are the usual fix, with new Map(parsed) on the way back.
Small one on your prototype point: if you want a dictionary without inherited keys but do not need Map, Object.create(null) gives you an object with no prototype at all. Handy when the keys come from user input and something might be called "constructor" or "proto".