Objects and prototypes
An object in JavaScript is a set of properties, where each property is described not only by its value but by a hidden descriptor: the flags writable, enumerable, configurable. These flags decide whether a property can be overwritten, whether enumeration sees it, and whether it can be deleted. You create most properties with a plain assignment and never notice descriptors — until a class method fails to show up in Object.keys, or a frozen object silently ignores a write.
This topic covers the mechanics of objects themselves: how they are created, how descriptors and accessors work, in what order keys enumerate, and why copying is shallow by default. The prototype chain — how objects inherit from one another — gets its own topic, Prototypes & Inheritance. The full map is in the layers below.
Topic map
- Object creation — the literal
{},Object.create, a constructor withnewandclass, plus computed property names. - Property descriptors — the
writable/enumerable/configurableflags,defineProperty, andgetOwnPropertyDescriptor. - Accessor properties —
get/setinstead of a stored value — computing on read and validating on write. - Property enumeration —
Object.keys/values/entriesversusfor...in, theenumerableflag, and why class methods are invisible. - Property order — integer keys ascending, then string keys in insertion order, then symbols.
- Object copying — shallow copy (
spread,Object.assign) versus deep (structuredClone) and the shared-reference trap.
Common traps
| Mistake | Consequence |
|---|---|
Treating {...o} as a deep copy | Nested objects are shared by reference — a mutation shows in the original |
Expecting a class method in Object.keys | Prototype methods are non-enumerable and are not there |
Iterating an object with for...in without hasOwnProperty | Inherited properties from the prototype leak into the loop |
| Relying on insertion order for numeric keys | Integer keys always come first ascending, not as inserted |
Assigning to a property that has only a get | Silently ignored (or throws in strict mode): the accessor has no set |
Thinking Object.freeze protects nested objects | The freeze is shallow — the inner object stays mutable |
Interview relevance
Objects are asked to check whether you understand the difference between value and reference and know that a property is not just "a key and a value" but a record with flags. A candidate who answers the copying question with "spread copies one level, the nested part stays shared by reference" sounds more confident than one who confuses a copy with a clone.
Typical checks:
- The ways to create an object and how
Object.create(proto)differs from a literal. - What a descriptor is and which flags it holds; why
definePropertyexists. - Why
for...insees inherited keys whileObject.keysdoes not. - The key enumeration order and why
{2:'a',1:'b'}yields1,2. - Shallow versus deep copy and what
structuredClonedoes.
Common wrong answer: "Object.assign makes a deep copy." In fact it is a shallow, one-level copy — nested objects and arrays stay shared by reference, and a mutation through one side is visible on the other.