0
0
Javascriptprogramming~15 mins

Prototype chain in Javascript - Deep Dive

Choose your learning style9 modes available
Overview - Prototype chain
What is it?
The prototype chain is a way JavaScript objects inherit properties and methods from other objects. When you try to access a property on an object, JavaScript looks for it on that object first. If it doesn't find it, it looks up the chain to the object's prototype, then the prototype's prototype, and so on until it finds the property or reaches the end. This chain of linked objects is called the prototype chain.
Why it matters
Without the prototype chain, JavaScript would need to copy all properties and methods to every object, wasting memory and making code harder to maintain. The prototype chain allows objects to share behavior efficiently, making JavaScript flexible and powerful. Understanding it helps you write better code and debug tricky inheritance issues.
Where it fits
Before learning the prototype chain, you should know basic JavaScript objects and properties. After this, you can learn about classes, inheritance, and advanced object-oriented patterns in JavaScript.
Mental Model
Core Idea
The prototype chain is a linked path JavaScript follows to find properties and methods an object doesn’t have itself.
Think of it like...
Imagine a family tree where you ask your parents for something you don’t have. If they don’t have it, you ask your grandparents, and so on until someone has it or you reach the oldest ancestor.
Object → Prototype → Prototype's Prototype → ... → null
  │           │                    
  └─ property? └─ property? └─ property? └─ end
Build-Up - 7 Steps
1
FoundationObjects and properties basics
🤔
Concept: Learn how objects store properties and how to access them.
In JavaScript, objects are collections of key-value pairs called properties. You can access a property using dot notation or brackets. Example: const obj = { name: 'Alice', age: 25 }; console.log(obj.name); // 'Alice' console.log(obj['age']); // 25
Result
You can get or set values inside objects using keys.
Understanding how objects hold data is the first step to seeing how inheritance works through prototypes.
2
FoundationWhat is a prototype object?
🤔
Concept: Every JavaScript object has a hidden link to another object called its prototype.
When you create an object, JavaScript sets a hidden property called [[Prototype]] that points to another object. This prototype can have properties and methods that the original object can use. Example: const parent = { greet() { return 'Hello'; } }; const child = Object.create(parent); console.log(child.greet()); // 'Hello'
Result
child can use greet() even though it’s not its own property.
Knowing that objects link to prototypes explains how properties can be shared without copying.
3
IntermediateHow property lookup works
🤔Before reading on: do you think JavaScript copies properties from the prototype to the object or just looks them up when needed? Commit to your answer.
Concept: JavaScript looks up properties along the prototype chain instead of copying them.
When you access a property, JavaScript first checks the object itself. If it’s not there, it checks the prototype, then the prototype’s prototype, and so on until it finds the property or reaches null. Example: const grandparent = { sayHi() { return 'Hi'; } }; const parent = Object.create(grandparent); const child = Object.create(parent); console.log(child.sayHi()); // 'Hi'
Result
child can use sayHi() found on grandparent via the chain.
Understanding lookup instead of copying helps explain memory efficiency and dynamic behavior.
4
IntermediateModifying prototypes affects all linked objects
🤔Before reading on: if you add a method to a prototype, do existing objects linked to it get the new method automatically? Commit to your answer.
Concept: Changing a prototype changes behavior for all objects linked to it immediately.
If you add or change a property on a prototype, all objects that inherit from it see the change right away. Example: const proto = {}; const obj1 = Object.create(proto); const obj2 = Object.create(proto); proto.sayBye = () => 'Bye'; console.log(obj1.sayBye()); // 'Bye' console.log(obj2.sayBye()); // 'Bye'
Result
Both obj1 and obj2 can use the new sayBye method.
This shows how prototypes enable shared behavior and dynamic updates across many objects.
5
IntermediatePrototype chain ends with null
🤔
Concept: The prototype chain always ends at null, which means no more objects to check.
Every prototype chain eventually reaches null, which signals the end of the chain. Example: const obj = {}; console.log(Object.getPrototypeOf(obj)); // Object.prototype console.log(Object.getPrototypeOf(Object.prototype)); // null
Result
JavaScript stops looking for properties once it reaches null.
Knowing the chain’s end prevents infinite loops and clarifies property lookup limits.
6
AdvancedUsing __proto__ and Object.getPrototypeOf
🤔Before reading on: do you think __proto__ and Object.getPrototypeOf do the same thing or different? Commit to your answer.
Concept: You can access an object's prototype using __proto__ or Object.getPrototypeOf, but one is standard and safer.
The __proto__ property is a legacy way to access an object's prototype. Object.getPrototypeOf(obj) is the standard method. Example: const obj = {}; console.log(obj.__proto__ === Object.getPrototypeOf(obj)); // true
Result
Both give the prototype, but Object.getPrototypeOf is preferred.
Understanding these access methods helps with debugging and advanced prototype manipulation.
7
ExpertPrototype chain and performance surprises
🤔Before reading on: do you think deep prototype chains slow down property access significantly? Commit to your answer.
Concept: Long prototype chains can slow property access, but JavaScript engines optimize common cases heavily.
While property lookup walks the prototype chain, modern JavaScript engines use hidden classes and inline caches to speed up access. However, very deep or dynamic prototype chains can still cause performance hits. Example: function A() {} function B() {} B.prototype = Object.create(A.prototype); function C() {} C.prototype = Object.create(B.prototype); // Deep chains like this can be slower in some cases.
Result
Property access remains fast usually, but deep chains can degrade performance.
Knowing engine optimizations and limits helps write efficient code and avoid subtle slowdowns.
Under the Hood
JavaScript objects have an internal hidden link called [[Prototype]] pointing to another object. When accessing a property, the engine first checks the object itself. If missing, it follows the [[Prototype]] link to the next object, repeating until it finds the property or reaches null. This chain lookup is done at runtime, enabling dynamic inheritance and shared behavior without copying properties.
Why designed this way?
The prototype chain was designed to allow flexible inheritance without duplicating code or data. Early JavaScript needed a lightweight way to share methods across many objects. Classical class-based inheritance was avoided to keep the language simple and dynamic. This design trades off some lookup speed for great flexibility and memory efficiency.
┌─────────┐     [[Prototype]]     ┌──────────────┐     [[Prototype]]     ┌───────────────┐
│  Object │ ───────────────────▶ │  Prototype   │ ───────────────────▶ │  Prototype's  │
│  (child)│                      │   Object     │                      │  Prototype    │
└─────────┘                      └──────────────┘                      └───────────────┘
       │                                  │                                    │
       │ property found?                   │ property found?                     │ property found?
       └─────────────Yes───────────────▶ │                                    │
                                         └─────────────Yes───────────────────▶

If no property found at any step, lookup ends at null.
Myth Busters - 4 Common Misconceptions
Quick: Does changing a property on an object’s prototype copy it to the object? Commit yes or no.
Common Belief:Changing a prototype’s property copies it to all objects linked to it.
Tap to reveal reality
Reality:Changing a prototype’s property changes it only on the prototype; objects inherit it dynamically without copying.
Why it matters:Believing in copying leads to confusion about why changes to prototypes affect all linked objects immediately.
Quick: Is the prototype chain the same as classical inheritance? Commit yes or no.
Common Belief:The prototype chain works exactly like classical class inheritance in other languages.
Tap to reveal reality
Reality:The prototype chain is a dynamic delegation system, not classical inheritance; objects inherit directly from other objects, not classes.
Why it matters:Misunderstanding this causes wrong assumptions about how inheritance and method overriding work in JavaScript.
Quick: Does every object have its own copy of inherited methods? Commit yes or no.
Common Belief:Each object has its own copy of methods inherited from its prototype.
Tap to reveal reality
Reality:Objects share methods via the prototype; methods are not copied but referenced through the chain.
Why it matters:Thinking methods are copied wastes mental effort and leads to inefficient code design.
Quick: Can the prototype chain form a loop? Commit yes or no.
Common Belief:It’s possible to create a circular prototype chain causing infinite loops.
Tap to reveal reality
Reality:JavaScript prevents circular prototype chains; the chain always ends at null.
Why it matters:Believing loops exist causes unnecessary fear of infinite loops during property lookup.
Expert Zone
1
Modifying Object.prototype affects all objects, which can cause unexpected bugs if done carelessly.
2
Shadowing a property on an object hides the prototype’s property but does not delete it from the prototype.
3
The prototype chain lookup is dynamic, so changing prototypes at runtime can alter behavior of existing objects.
When NOT to use
Avoid relying heavily on deep prototype chains for performance-critical code; prefer composition or class-based inheritance patterns. Also, do not modify built-in prototypes like Array.prototype in production code to prevent conflicts.
Production Patterns
Developers use prototype chains to implement inheritance in frameworks and libraries. For example, JavaScript classes use prototypes under the hood. Prototype chains enable method sharing in libraries like React and Node.js core modules.
Connections
Classical inheritance
Prototype chain is a form of inheritance but differs from classical class-based inheritance.
Understanding prototype chains clarifies how JavaScript’s inheritance is more flexible and dynamic than classical models.
Delegation pattern
Prototype chain is an implementation of the delegation design pattern where objects delegate behavior to linked prototypes.
Recognizing delegation helps understand how behavior sharing works without copying.
Biological evolution
Prototype chain resembles how traits pass through generations with variations and shared features.
Seeing prototype chains like evolution shows how objects inherit and override properties dynamically over time.
Common Pitfalls
#1Modifying a prototype property expecting it to copy to objects.
Wrong approach:const proto = { greet() { return 'Hi'; } }; const obj = Object.create(proto); proto.greet = () => 'Hello'; console.log(obj.greet()); // 'Hello' // But expecting obj to have its own greet method now
Correct approach:const proto = { greet() { return 'Hi'; } }; const obj = Object.create(proto); // obj.greet is still from proto, no copy made console.log(obj.greet()); // 'Hello' after proto change
Root cause:Misunderstanding that prototype properties are shared references, not copied.
#2Using __proto__ to set prototype in production code.
Wrong approach:const obj = {}; obj.__proto__ = anotherObj; // discouraged
Correct approach:const obj = Object.create(anotherObj); // standard and safer
Root cause:Not knowing __proto__ is legacy and can cause performance and compatibility issues.
#3Assuming methods are copied per object causing memory waste.
Wrong approach:function Person() { this.sayHi = function() { return 'Hi'; }; } const p1 = new Person(); const p2 = new Person();
Correct approach:function Person() {} Person.prototype.sayHi = function() { return 'Hi'; }; const p1 = new Person(); const p2 = new Person();
Root cause:Not using prototype to share methods leads to unnecessary duplication.
Key Takeaways
The prototype chain is how JavaScript objects inherit properties by linking to other objects dynamically.
Property lookup walks up the prototype chain until it finds the property or reaches the end at null.
Modifying a prototype affects all objects linked to it immediately, enabling shared behavior.
Understanding the prototype chain helps write efficient, maintainable JavaScript and debug inheritance issues.
Prototype chains differ from classical inheritance by using delegation instead of copying or classes.