Prototypal Inheritance


🧠 What is Prototypal Inheritance?
In JavaScript, objects can inherit properties and methods from other objects. This is known as prototypal inheritance.
Unlike classical languages (like Java, C++) that use classes, JavaScript uses prototypes under the hood to enable inheritance.
🔗 The Prototype Chain
Every JavaScript object has an internal link to another object called its prototype, accessible via [[Prototype]]
or .prototype
.
When you access a property or method:
JS looks for it on the object itself.
If not found, it goes to its prototype.
If still not found, it keeps walking up the prototype chain.
Ends at
Object.prototype
, whose prototype isnull
.
Example:
const person = {
greet() {
console.log("Hello!");
}
};
const john = Object.create(person); // john inherits from person
john.name = "John";
john.greet(); // "Hello!" — inherited from person
➡️ john
doesn’t have greet
, so it looks up the prototype chain to person
.
🧬 How to Create Inheritance
1. Using Object.create()
(Recommended)
const animal = {
eats: true
};
const dog = Object.create(animal);
dog.barks = true;
console.log(dog.eats); // true (inherited)
console.log(dog.barks); // true (own property)
Object.create(proto)
creates a new object and sets its[[Prototype]]
toproto
.
2. Constructor Functions + .prototype
Before ES6 classes, we used constructor functions:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
console.log("Hi, I'm " + this.name);
};
const alice = new Person("Alice");
alice.sayHello(); // Hi, I'm Alice
Here’s what happens:
alice.__proto__ === Person.prototype
JS finds
sayHello
onPerson.prototype
via prototype chain.
3. ES6 class
Syntax (syntactic sugar)
class Animal {
speak() {
console.log("Animal speaks");
}
}
class Dog extends Animal {
bark() {
console.log("Woof!");
}
}
const d = new Dog();
d.speak(); // Animal speaks
d.bark(); // Woof!
Under the hood, it’s still using prototypes, just more readable.
🔍 Behind the Scenes
Let’s say:
const obj = {};
This creates:
obj --> Object.prototype --> null
If we do:
const animal = {
speak() {
return "grrr";
}
};
const dog = Object.create(animal);
dog.bark = () => "woof";
dog.bark(); // "woof" → from dog
dog.speak(); // "grrr" → inherited from animal
⚙️ __proto__
vs .prototype
Term | Meaning |
obj.__proto__ | Refers to the object's internal [[Prototype]] . Used for lookup. |
Func.prototype | Used to define methods that should be inherited by all instances created with new Func() |
🛠 Real-World Example
function Vehicle(name) {
this.name = name;
}
Vehicle.prototype.drive = function () {
return this.name + " is driving";
};
function Car(name) {
Vehicle.call(this, name); // inherit properties
}
Car.prototype = Object.create(Vehicle.prototype); // inherit methods
Car.prototype.constructor = Car;
const honda = new Car("Honda");
console.log(honda.drive()); // Honda is driving
📚 Summary
Concept | Explanation |
Prototype | An object that other objects inherit from. |
Object.create() | Creates a new object with a specific prototype. |
.prototype | Used to define methods that are shared across all instances. |
__proto__ / [[Prototype]] | Points to the object’s prototype, used in property lookup. |
Prototype Chain | The lookup mechanism that traverses up the chain if a property/method isn't found. |
🚨 Gotchas & Tips
Changing
__proto__
directly is discouraged (useObject.setPrototypeOf()
orObject.create()
).You can override inherited methods — the object's own method always wins.
Be cautious of deep prototype chains — they can lead to performance hits and hard-to-debug errors.
Subscribe to my newsletter
Read articles from Sridhar Murali directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sridhar Murali
Sridhar Murali
Passionate Frontend Engineer with over 4.5 years of experience in frontend development and a strong previous experience in Quality Assurance of 4 years (2016-2020). Skilled in building responsive, high-quality applications using JavaScript frameworks like Ember.js and React.js, combining meticulous attention to detail from a QA background with a commitment to delivering seamless user experiences. Recognized for writing efficient, accessible code, strong debugging skills