Step 2 — Hidden Classes, delete, and Which Folklore Survives
Goal
Test the two most-repeated claims about object shapes against measurement. One survives; one does not.
Predict first
400,000 objects created and read, four ways:
A: { x, y, z } // consistent order
B: alternating { x, y, z } and { y, x, z } // inconsistent order
C: { x, y, z, tmp }, then delete o.tmp
D: { x, y, z, tmp }, then o.tmp = undefined
Rank them, and predict B and C as multiples of A. Most engineers rank B as the serious problem.
Run
npm run shapes
Expected output:
variant | median ms | vs A
A same property order | 5.60 | 1.00x
B alternating property order | 6.40 | 1.14x
C delete o.tmp (dictionary mode) | 66.80 | 11.93x
D o.tmp = undefined instead | 5.50 | 0.98x
What just happened
Property order: 1.14×. Real, but a fraction of what the folklore implies. It is worth doing right because it is free, not because it is urgent. Treat as hygiene.
delete: 11.93×. The claim people wave away is the one that bites. Deleting a property drops
the object out of the shape system entirely into dictionary mode — a hash map, no hidden class,
no IC. Every subsequent read on every such object is slow, permanently.
o.tmp = undefined: 0.98×. Free. The shape is preserved; only the value changes.
What to do instead of delete
o.tmp = undefined; // shape preserved; leaves the key present
const { tmp, ...rest } = o; // new object, clean shape — usually right
const m = new Map(); m.delete(k); // dynamic keys that get removed: use the right type
The third is the structural answer. If keys are dynamic and deleted, a plain object is being used
as a dictionary, and Map is the type designed for that — it never enters dictionary mode, and
(fe-02) WeakMap additionally solves the retention question.
Why this ordering is worth remembering: it is a clean case of measurement inverting received wisdom. The advice everyone repeats is worth 1.14×; the practice everyone tolerates is worth 11.9×.
Checkpoint
docs/verification.md Checkpoint 2.