Prototype Chain
Every JavaScript object has an internal [[Prototype]] link — a reference to another object. When you access a property, JS looks up the chain until it finds it or reaches null. This is the foundation of all inheritance in JavaScript.
Understanding __proto__ and prototype
const animal = {
breathes: true,
eat() { return 'Eating...'; }
};
const dog = Object.create(animal); // dog.__proto__ = animal
dog.name = 'Rex';
dog.bark = function() { return 'Woof!'; };
console.log(dog.bark()); // Woof! ← own property
console.log(dog.eat()); // Eating! ← found on animal (prototype)
console.log(dog.breathes); // true ← found on animal
console.log(dog.hasOwnProperty('name')); // true
console.log(dog.hasOwnProperty('eat')); // false (on prototype)
Constructor Functions and prototype
function Person(name, age) {
this.name = name;
this.age = age;
}
// Methods on prototype — shared across ALL instances (not duplicated)
Person.prototype.greet = function() {
return `Hi, I'm ${this.name}`;
};
Person.prototype.isAdult = function() {
return this.age >= 18;
};
const p1 = new Person('Rahul', 25);
const p2 = new Person('Priya', 30);
console.log(p1.greet()); // Hi, I'm Rahul
console.log(p2.greet()); // Hi, I'm Priya
// Both share the SAME greet function (prototype) — no memory duplication
ES6 Classes — Syntactic Sugar
class Animal {
#sound; // private field (ES2022)
constructor(name, sound) {
this.name = name;
this.#sound = sound;
}
speak() {
return `${this.name} says ${this.#sound}`;
}
static create(name, sound) {
return new Animal(name, sound);
}
}
class Dog extends Animal {
constructor(name) {
super(name, 'Woof'); // call parent constructor
}
fetch(item) {
return `${this.name} fetches ${item}`;
}
}
const dog = new Dog('Rex');
console.log(dog.speak()); // Rex says Woof
console.log(dog.fetch('ball')); // Rex fetches ball
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
Prototype Chain Lookup
// Chain: dog → Dog.prototype → Animal.prototype → Object.prototype → null
const dog = new Dog('Rex');
// toString() found on Object.prototype
console.log(dog.toString()); // [object Object]
// Check chain manually
console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true
Q: What is the difference between __proto__ and prototype?
prototype is a property of constructor functions — it defines what the prototype will be for objects created with new. __proto__ (or [[Prototype]]) is the actual prototype link on every object instance. Object.getPrototypeOf() is the preferred way to access it.
Q: Are ES6 classes fundamentally different from prototype-based inheritance?
No. Classes are syntactic sugar over the existing prototype system. class Dog extends Animal compiles to the same prototype chain as manual prototype assignment. The engine still uses [[Prototype]] under the hood.
Comments (0)
No comments yet. Be the first!
Leave a Comment