Reading — step 1 of 7
Learn
Every property in a JavaScript object has metadata — its descriptor. You usually never see them, but tools like Object.freeze, Object.defineProperty, and class accessor syntax all manipulate them.
What's a descriptor?
Four flags every plain property has:
value— the actual valuewritable— can it be reassigned withobj.x = ...?enumerable— does it show up inObject.keys,for...in,JSON.stringify?configurable— can the descriptor itself be changed (or property deleted)?
Assigning normally (obj.x = 1) creates a property with all four set to true.
Object.defineProperty — fine control
Used for hidden internal properties on objects, locking down library APIs, defining constants.
Getters and setters (accessor properties)
Instead of a stored value, define functions that run when the property is accessed:
In classes:
Getters/setters look like properties from the outside but compute on access.
Object.freeze — make it immutable
Freeze sets writable=false and configurable=false on every property AND prevents adding new properties. SHALLOW — nested objects are still mutable.
For deep immutability:
Object.seal — between freeze and normal
Object.preventExtensions(obj)— can't ADD properties; existing still mutableObject.seal(obj)— also can't DELETE; existing still writableObject.freeze(obj)— also can't WRITE
Private fields (ES2022)
For genuine privacy in classes, use #-prefixed fields:
Private fields are syntax-level private — not just convention. Reflection won't find them.
Common mistakes
- Confusing freeze with deep freeze — Object.freeze is shallow.
- Using underscore prefix as 'privacy' —
_xis a convention, anyone can read it. Use#for real privacy. - Forgetting strict-mode behavior — assignments to frozen properties silently fail in sloppy mode but throw in strict.
- Creating non-enumerable properties accidentally — using
Object.definePropertywithout specifying enumerable defaults all flags to false. - Accessor properties in JSON — getters run during JSON.stringify (their return value is serialized) but don't round-trip; the parse side won't recreate the getter.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…