In JavaScript, every object has a hidden internal property called [[Prototype]], which refers to another object. This object is known as the prototype.
The prototype is used for inheritance: if a property or method is not found on the object itself, JavaScript looks for it in the prototype, and continues up the chain until it finds it—or reaches the end (null).
🔹 Why Use Prototypes?
Prototypes allow JavaScript to:
- Share methods and properties across all instances of a constructor
- Save memory (methods are not duplicated per instance)
- Implement inheritance in a flexible, object-based way
🔹 How It Works: A Simple Example
javascriptCopyEditconst person = {
greet() {
console.log("Hello!");
}
};
const user = Object.create(person);
user.name = "Alice";
user.greet(); // "Hello!"
Explanation:
userdoes not have agreet()method.- JavaScript looks into
user‘s prototype (person) and findsgreet().
🔹 The Prototype Chain
javascriptCopyEdituser → person → Object.prototype → null
JavaScript walks up this prototype chain when accessing properties or methods.
🔹 Constructor Functions and Prototypes
When you create objects using constructor functions, you can attach methods to the constructor’s prototype so all instances share them.
javascriptCopyEditfunction Person(name) {
this.name = name;
}
// Add method to prototype
Person.prototype.sayHello = function () {
console.log("Hi, I'm " + this.name);
};
const alice = new Person("Alice");
const bob = new Person("Bob");
alice.sayHello(); // "Hi, I'm Alice"
bob.sayHello(); // "Hi, I'm Bob"
Here, both alice and bob share the same sayHello method from Person.prototype.
🔹 Class Syntax (ES6) — Under the Hood
ES6 introduced the class syntax, but it still uses prototypes behind the scenes.
javascriptCopyEditclass Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
const dog = new Animal("Rex");
dog.speak(); // "Rex makes a sound."
Under the hood:
Animal.prototype.speakis created.dog.__proto__ === Animal.prototypeistrue.
🔍 Inspecting Prototypes
You can inspect or interact with prototypes using:
Object.getPrototypeOf(obj)obj.__proto__(legacy but commonly used)Object.setPrototypeOf(obj, proto)
Example:
javascriptCopyEditconsole.log(Object.getPrototypeOf(dog) === Animal.prototype); // true
🧠 Inheritance with Prototypes
JavaScript allows inheritance via prototypes:
javascriptCopyEditfunction Vehicle(type) {
this.type = type;
}
Vehicle.prototype.describe = function () {
console.log(`This is a ${this.type}.`);
};
function Car(brand) {
Vehicle.call(this, "car");
this.brand = brand;
}
// Inherit from Vehicle
Car.prototype = Object.create(Vehicle.prototype);
Car.prototype.constructor = Car;
Car.prototype.honk = function () {
console.log(`${this.brand} says beep!`);
};
const myCar = new Car("Toyota");
myCar.describe(); // "This is a car."
myCar.honk(); // "Toyota says beep!"
📝 Summary Table
| Concept | Description |
|---|---|
prototype | Property of constructor functions |
__proto__ | Property of objects pointing to their prototype |
| Inheritance | Achieved by walking the prototype chain |
| Efficiency | Methods are shared via prototypes |
✅ Conclusion
Prototypes are the backbone of inheritance in JavaScript. While newer syntax like class makes things more readable, understanding how prototypes work under the hood helps you:
- Debug tricky inheritance bugs
- Optimize memory by sharing methods
- Work with frameworks and tools that rely on prototypal inheritance