Interview question
How do you implement inheritance using prototype-based patterns (before ES6 classes)? ES6 classes से पहले prototype-based patterns से inheritance कैसे implement करें?
Answer
Before ES6, inheritance was implemented by manually linking one constructor's prototype to another's, then calling the parent constructor explicitly.
// Parent constructor
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return `${this.name} makes a sound`;
};
// Child constructor
function Dog(name, breed) {
Animal.call(this, name); // step 1: call parent constructor, bind 'this'
this.breed = breed;
}
// step 2: link Dog's prototype to a new object based on Animal's prototype
Dog.prototype = Object.create(Animal.prototype);
// step 3: fix the constructor reference (Object.create overwrote it)
Dog.prototype.constructor = Dog;
// step 4: add/override methods on the child's prototype
Dog.prototype.speak = function() {
return `${Animal.prototype.speak.call(this)}, specifically barking`;
};
const rex = new Dog('Rex', 'Labrador');
console.log(rex.speak()); // Rex makes a sound, specifically barking
console.log(rex instanceof Dog); // true
console.log(rex instanceof Animal); // true - inheritance chain works
// Common mistake: setting prototype directly instead of Object.create
function WrongDog(name) {
Animal.call(this, name);
}
WrongDog.prototype = Animal.prototype; // BAD - shares the exact same object
WrongDog.prototype.bark = function() { return 'Woof'; };
// This pollutes Animal.prototype too, affecting ALL Animal instances
// The ES6 class equivalent (syntactic sugar for the same pattern)
class AnimalES6 {
constructor(name) { this.name = name; }
speak() { return `${this.name} makes a sound`; }
}
class DogES6 extends AnimalES6 {
constructor(name, breed) {
super(name);
this.breed = breed;
}
}ES6 से पहले, inheritance manually एक constructor के prototype को दूसरे से link करके implement होती थी, फिर parent constructor को explicitly call किया जाता था।
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return `${this.name} makes a sound`;
};
function Dog(name, breed) {
Animal.call(this, name); // step 1: parent constructor call
this.breed = breed;
}
// step 2: Dog का prototype Animal से link करना
Dog.prototype = Object.create(Animal.prototype);
// step 3: constructor reference fix करना
Dog.prototype.constructor = Dog;
// step 4: child prototype पर methods add/override करना
Dog.prototype.speak = function() {
return `${Animal.prototype.speak.call(this)}, specifically barking`;
};
const rex = new Dog('Rex', 'Labrador');
console.log(rex.speak());
console.log(rex instanceof Dog); // true
console.log(rex instanceof Animal); // true
// गलती: prototype सीधे set करना
function WrongDog(name) {
Animal.call(this, name);
}
WrongDog.prototype = Animal.prototype; // गलत - same object share होता है
// ES6 class equivalent
class AnimalES6 {
constructor(name) { this.name = name; }
speak() { return `${this.name} makes a sound`; }
}
class DogES6 extends AnimalES6 {
constructor(name, breed) {
super(name);
this.breed = breed;
}
}Was this answer clear?