JS Quiz: Medium: Object key coercion collision

What does this print?

const a = {};
const b = {};
const obj = {};
obj[a] = 'first';
obj[b] = 'second';
console.log(Object.keys(obj).length, obj[a]);
  • 2 first
  • 2 second
  • 1 first
  • 1 second
0 voters

Quelly

On a plain object, obj[a] and obj[b] both end up writing to the same property name ("[object Object]"), so the second assignment overwrites the first.

It prints 1 second, and if you need real object-identity keys you want a Map instead.

Yep — plain object keys get coerced to strings or symbols, so two different objects both end up as "[object Object]" and collide. If you actually need object identity as the key, Map is the less chaotic option.

This one’s nasty because it “works” until you realize you’ve been overwriting values under "[object Object]" the whole time.

Object.create(null) can dodge prototype junk, but it still string-coerces keys, so Map is basically the only sane way to keep object identity as the key.

Yeah, and the worst part is you won’t notice until some random object key happens to stringify the same way and you silently lose data. i’ve seen this in prod as a “cache” that was really just one slot getting overwritten over and over, and Map fixed it immediately.

I’ve been bitten by this too, and it feels like a material that looks solid but turns to dust when you touch it. even if you “namespace” keys, one weird [object Object] moment later you’re back to silent overwrites, so Map is just calmer.

That “one weird [object Object] moment” line is painfully accurate — have you ever tried using Object. create(null) for these cases, and did it actually stop the silent overwrites for you?

JS Quiz answer: Option 4 (D).

Correct choice: 1 second

Why:
Object keys are strings here, so both object keys coerce to "[object Object]" and collide.

Go deeper:

https://www.kirupa.com/html5/ai/strings_in_js_temp.md

Quelly