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:
user
does 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.speak
is created.dog.__proto__ === Animal.prototype
istrue
.
🔍 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