Suggest an editImprove this articleRefine the answer for “Property lookup in the prototype chain”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)The **prototype chain** is the order in which JavaScript searches for an object's property: first on the object itself, then on its prototype, then the prototype's prototype, and so on up to `null`. If the property is not found anywhere, the result is `undefined`. **Key point:** the search always starts at the object and moves up the prototype chain until the property is found or the chain ends at `null`.Shown above the full answer for quick recall.Answer (EN)Image## Short answer When you access an object's property, for example: ```javascript obj.prop ``` JavaScript **searches for this property** in the following order: 1. First in **the object itself** (`obj`); 2. If not found - in its **prototype** (`obj.__proto__` or `Object.getPrototypeOf(obj)`); 3. Then - in **the prototype's prototype**, and so on; 4. Until it reaches `null` (the top of the chain). If the property is not found anywhere - the result is `undefined`. This sequence is called the **prototype chain**. --- ## Example: step-by-step search ```javascript const animal = { eats: true }; const dog = Object.create(animal); dog.barks = true; console.log(dog.barks); // found in dog → true console.log(dog.eats); // not in dog → look in animal → true console.log(dog.toString); // not in animal → look in Object.prototype → [Function] console.log(dog.fly); // not found anywhere → undefined ``` Chain: ```javascript dog → animal → Object.prototype → null ``` --- ## Visually ```javascript dog { barks: true } ↑ | animal { eats: true } ↑ | Object.prototype { toString(), hasOwnProperty(), ... } ↑ | null ``` --- ## Algorithm under the hood (step by step) When `obj.prop` is executed: 1. JS checks: does the property `prop` exist **on the object itself** (own property)? → if **yes** - return its value. → if **no** - move on. 2. JS gets the object's prototype: ```javascript const parent = Object.getPrototypeOf(obj); ``` 3. Checks whether `prop` exists on `parent`. 4. Repeats the steps until: - the property is found - or the prototype equals `null` All of this happens **dynamically**, without copying properties. --- ## When writing a property (`obj.prop = value`) Here the mechanism is a bit different: - If the property **exists on the object itself**, → it is simply overwritten. - If not - **a new property is created** on `obj` (not on the prototype). - The prototype is not touched at all. ```javascript const animal = { eats: true }; const dog = Object.create(animal); dog.eats = false; // creates a new property on dog console.log(dog.eats); // false (own) console.log(animal.eats); // true (on the prototype, unchanged) ``` --- ## Reading and writing use different chains | Operation | Where it looks | What it does | |---|---|---| | `obj.prop` (read) | Looks in `obj`, then up the chain | Returns the first one found | | `obj.prop = value` (write) | Always writes to `obj`, if `writable: true` | Does not change the prototype | | `delete obj.prop` | Deletes only on `obj` | Does not affect the prototype | --- ## If the chain has a getter or setter If a **getter** (`get prop()`) is found at any level, it **executes**. If a **setter** is found, it **executes on write**. ```javascript const animal = { get info() { return 'Animal info'; } }; const dog = Object.create(animal); console.log(dog.info); // "Animal info" - the prototype's getter was called ``` That is, prototypes can contain "reactive" properties, not just data. --- ## Example with a "deep" chain ```javascript const a = { level: 'A' }; const b = Object.create(a); const c = Object.create(b); const d = Object.create(c); console.log(d.level); // "A" ``` The search goes through 4 objects before finding `level` on `a`. --- ## Engine optimization JS engines (V8, SpiderMonkey, etc.) **optimize the prototype chain**: - they create internal "shape" maps (object structures); - they cache found properties; - the cache is invalidated when the prototype or properties change. That's why *changing the prototype at runtime* (`Object.setPrototypeOf`) is a slow operation, and it is best avoided. --- ## Example: what happens if the prototype is `null` ```javascript const pure = Object.create(null); pure.key = 'value'; console.log(pure.toString); // undefined (no Object.prototype) ``` Here the chain breaks immediately: ```javascript pure → null ``` The search stops instantly if the prototype equals `null`. --- ## SUMMARY | Stage | What happens | |---|---| | 1 | JS looks for the property on the object itself | | 2 | If not found - it goes to `[[Prototype]]` | | 3 | It continues up the chain | | 4 | If it reaches `null` - it returns `undefined` | | Note | On write, a new property is created on the object, not on the prototype | | Note | Getters/setters in the chain are also taken into account |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.