Introduction
JavaScript is a prototype-based language, which means that inheritance — the mechanism that allows one object to access properties and methods of another — is implemented through prototypes, not classical classes (though the classsyntax introduced in ES6 provides a cleaner abstraction over it).
Download the Codeflare Mobile for iOS
In simple terms:
Every object in JavaScript can have another object as its prototype, from which it inherits properties and methods.
Understanding Prototypes
Every JavaScript object has an internal link to another object called its prototype.
This prototype object is referenced by the special property [[Prototype]] (or __proto__ in most environments).
When you try to access a property on an object and it’s not found, JavaScript looks up the prototype chain — the object’s prototype, then the prototype’s prototype, and so on — until it finds it or reaches the end of the chain (null).
Example:
const person = {
greet() {
console.log("Hello!");
}
};
const student = Object.create(person); // student inherits from person
student.study = function() {
console.log("Studying...");
};
student.greet(); // Output: Hello! (inherited from person)
student.study(); // Output: Studying...
In the example above:
studentinherits frompersonviaObject.create().- When
student.greet()is called, JavaScript doesn’t findgreetonstudent, so it looks up to its prototype —person— and finds it there.
The Prototype Chain 🧬
Here’s how the lookup works internally:
student → person → Object.prototype → null
Each arrow represents the prototype link.
When you create a new object, its prototype determines what it can inherit.
Constructor Functions and Prototypes
Before ES6 class syntax, constructor functions were used to create objects that share methods through their prototype.
Example:
function Car(make, model) {
this.make = make;
this.model = model;
}
// Add method to Car's prototype
Car.prototype.start = function() {
console.log(`${this.make} ${this.model} started.`);
};
const car1 = new Car("Toyota", "Camry");
const car2 = new Car("Honda", "Civic");
car1.start(); // Toyota Camry started.
car2.start(); // Honda Civic started.
Here’s what happens:
- The
newkeyword creates a new object. - It sets the object’s prototype to
Car.prototype. - It runs the
Carfunction withthisbound to the new object. - The object inherits methods from
Car.prototype.
Prototype Inheritance in ES6 Classes
The ES6 class syntax is syntactic sugar over the prototype-based model.
Under the hood, it still uses prototypes for inheritance.
Example:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog("Buddy");
dog.speak(); // Buddy barks.
Here’s what happens:
Doginherits fromAnimalvia theextendskeyword.- The prototype chain becomes:
dog → Dog.prototype → Animal.prototype → Object.prototype → null
Object.create() for Inheritance
The Object.create() method allows you to create a new object using an existing one as its prototype — a clean and direct way to set up inheritance without constructors.
Example:
const animal = {
speak() {
console.log(`${this.name} makes a noise.`);
}
};
const cat = Object.create(animal);
cat.name = "Whiskers";
cat.speak(); // Whiskers makes a noise.
Here, cat inherits from animal using Object.create().
Prototype vs. proto
prototypeis a property of constructor functions and classes — it defines what will be inherited by instances created withnew.__proto__is the actual prototype of an instance object, pointing to the object it inherits from.
Example:
function Car() {}
const myCar = new Car();
console.log(Car.prototype === myCar.__proto__); // true
Why Use Prototypes?
- Memory efficiency – Shared methods are stored once in the prototype, not duplicated per instance.
- Reusability – You can easily extend or modify behaviors by updating prototypes.
- Flexibility – Supports dynamic inheritance and extension of objects at runtime.
Quick Summary
| Concept | Description |
|---|---|
| Prototype | The object another object inherits from. |
| Prototype Chain | The linked chain of prototypes used for property lookup. |
| Constructor Function | A function that initializes an object, with shared methods on its prototype. |
| Object.create() | Creates an object using another as its prototype. |
| ES6 Classes | A syntactic sugar for prototype-based inheritance. |
Example: Multi-Level Inheritance
class LivingThing {
breathe() {
console.log("Breathing...");
}
}
class Animal extends LivingThing {
eat() {
console.log("Eating...");
}
}
class Bird extends Animal {
fly() {
console.log("Flying...");
}
}
const eagle = new Bird();
eagle.breathe(); // Breathing...
eagle.eat(); // Eating...
eagle.fly(); // Flying...
Final Thoughts
JavaScript’s prototype system is powerful, flexible, and dynamic.
Even though class syntax feels familiar to developers from other languages, under the hood it’s still prototypes doing the heavy lifting.
Understanding how prototypes and inheritance work allows you to:
- Write efficient, memory-friendly code.
- Build scalable class hierarchies.
- Debug and extend JavaScript objects with confidence.

Latest tech news and coding tips.