Introductions
JavaScript uses a prototype-based inheritance system. Every JavaScript object can have a prototype, and objects can access properties and methods through the prototype chain.
In this chapter, you will practice prototypes, prototype, __proto__, constructor functions, prototype methods, prototype inheritance, Object.create(), and prototype chain concepts with easy step-by-step examples. JavaScript Prototypes and Inheritance practice questions with solutions help to understand the concepts.
Question 1: Create a Simple Prototype Method
Problem
Create a Person constructor function and add a greet() method to its prototype.
Solution
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log("Hello, " + this.name);
};
const person1 = new Person("Rahul");
person1.greet();
Output
Hello, Rahul
Step-by-step Explanation
First, we create a constructor function:
function Person(name) {
this.name = name;
}
Then we add a method to its prototype:
Person.prototype.greet = function() {
console.log("Hello, " + this.name);
};
Now every object created using new Person() can use greet().
const person1 = new Person("Rahul");
person1.greet();
The method does not need to be separately created inside every object. It is available through the prototype.
Question 2: Understand the prototype Property
Problem
Create a Student constructor and add a study() method to Student.prototype. Call the method from an object.
Solution
function Student(name) {
this.name = name;
}
Student.prototype.study = function() {
console.log(this.name + " is studying JavaScript.");
};
const student1 = new Student("Aman");
student1.study();
Output
Aman is studying JavaScript.
Step-by-step Explanation
The constructor creates the object:
function Student(name) {
this.name = name;
}
The prototype stores the shared method:
Student.prototype.study = function() {
console.log(this.name + " is studying JavaScript.");
};
When JavaScript cannot find study directly on student1, it looks through the object’s prototype.
This is called the prototype chain.
Question 3: Add a Shared Property Through a Prototype
Problem
Create a Car constructor with a brand property. Add a wheels property to its prototype and access both properties.
Solution
function Car(brand) {
this.brand = brand;
}
Car.prototype.wheels = 4;
const car1 = new Car("Toyota");
console.log(car1.brand);
console.log(car1.wheels);
Output
Toyota
4
Step-by-step Explanation
brand is created directly on the object:
this.brand = brand;
But wheels is added to the prototype:
Car.prototype.wheels = 4;
So JavaScript finds wheels through the prototype chain when we write:
car1.wheels
This demonstrates the difference between an own property and an inherited property.
Question 4: Check an Object’s Prototype
Problem
Create an object from a constructor function and check whether its prototype is the constructor’s prototype.
Solution
function Person(name) {
this.name = name;
}
const person1 = new Person("Riya");
console.log(
Object.getPrototypeOf(person1) === Person.prototype
);
Output
true
Step-by-step Explanation
When an object is created using:
new Person("Riya");
its internal prototype is linked to:
Person.prototype
We can inspect that relationship using:
Object.getPrototypeOf(person1)
So:
Object.getPrototypeOf(person1) === Person.prototype
returns:
true
Object.getPrototypeOf() is the standard way to inspect an object’s prototype.
Question 5: Use Object.create() for Prototype Inheritance
Problem
Create a person object with a greet() method. Create another object using Object.create(person) and use the inherited method.
Solution
const person = {
greet: function() {
console.log("Hello!");
}
};
const student = Object.create(person);
student.greet();
Output
Hello!
Step-by-step Explanation
This creates the first object:
const person = {
greet: function() {
console.log("Hello!");
}
};
Then:
const student = Object.create(person);
creates a new object whose prototype is person.
Therefore, student can access:
student.greet();
even though greet() is not an own property of student.
Question 6: Create Prototype Inheritance with Constructor Functions
Problem
Create an Animal constructor with an eat() method. Create a Dog constructor that inherits from Animal.
Solution
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(this.name + " is eating.");
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log(this.name + " is barking.");
};
const dog = new Dog("Bruno");
dog.eat();
dog.bark();
Output
Bruno is eating.
Bruno is barking.
Step-by-step Explanation
The parent constructor is:
function Animal(name) {
this.name = name;
}
Its method is added to the prototype:
Animal.prototype.eat = function() {
console.log(this.name + " is eating.");
};
The child constructor is:
function Dog(name) {
Animal.call(this, name);
}
This initializes the name property using the Animal constructor.
Then we connect the prototypes:
Dog.prototype = Object.create(Animal.prototype);
Now Dog objects can access methods from Animal.prototype.
Finally:
Dog.prototype.constructor = Dog;
restores the expected constructor reference after replacing Dog.prototype.
Question 7: Add a New Method to a Child Prototype
Problem
Create an Animal constructor with a eat() method. Create a Cat constructor that inherits from Animal and adds a meow() method.
Solution
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(this.name + " is eating.");
};
function Cat(name) {
Animal.call(this, name);
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.meow = function() {
console.log(this.name + " says Meow!");
};
const cat = new Cat("Mimi");
cat.eat();
cat.meow();
Output
Mimi is eating.
Mimi says Meow!
Step-by-step Explanation
The Cat object gets access to two types of methods.
From Animal.prototype:
cat.eat();
From Cat.prototype:
cat.meow();
The prototype chain looks like:
cat
↓
Cat.prototype
↓
Animal.prototype
↓
Object.prototype
↓
null
When JavaScript looks for a property, it searches through this chain.
Question 8: Override a Prototype Method
Problem
Create an Animal constructor with a sound() method. Create a Dog constructor that inherits from Animal but provides its own sound() method.
Solution
function Animal() {}
Animal.prototype.sound = function() {
console.log("Animal makes a sound.");
};
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.sound = function() {
console.log("Dog barks.");
};
const dog = new Dog();
dog.sound();
Output
Dog barks.
Step-by-step Explanation
Animal.prototype contains:
sound()
The Dog prototype also defines a method with the same name:
Dog.prototype.sound = function() {
console.log("Dog barks.");
};
When:
dog.sound();
is called, JavaScript finds sound() on Dog.prototype first.
Therefore, the child method is used instead of the inherited method.
This is called method overriding.
Question 9: Understand the Prototype Chain
Problem
Create an object with a custom prototype and check whether JavaScript can find properties through the prototype chain.
Solution
const animal = {
type: "Animal"
};
const dog = Object.create(animal);
dog.name = "Bruno";
console.log(dog.name);
console.log(dog.type);
Output
Bruno
Animal
Step-by-step Explanation
The dog object directly contains:
dog.name = "Bruno";
But type is not directly stored on dog.
It exists on its prototype:
animal.type
Because dog was created using:
Object.create(animal);
JavaScript searches the prototype when it cannot find type directly on dog.
The lookup works like this:
dog
↓
animal
↓
Object.prototype
↓
null
This lookup process is called the prototype chain.
Question 10: Build a Practical Prototype-Based System
Problem
Create a User constructor with a login() method. Create an Admin constructor that inherits from User and adds a deleteUser() method.
Solution
function User(name) {
this.name = name;
}
User.prototype.login = function() {
console.log(this.name + " logged in.");
};
function Admin(name) {
User.call(this, name);
}
Admin.prototype = Object.create(User.prototype);
Admin.prototype.constructor = Admin;
Admin.prototype.deleteUser = function(username) {
console.log(
this.name + " deleted user " + username
);
};
const admin = new Admin("Rahul");
admin.login();
admin.deleteUser("Aman");
Output
Rahul logged in.
Rahul deleted user Aman
Step-by-step Explanation
The User constructor contains common user information:
function User(name) {
this.name = name;
}
The shared login behavior is placed on its prototype:
User.prototype.login = function() {
console.log(this.name + " logged in.");
};
The Admin constructor reuses the parent constructor:
User.call(this, name);
Then its prototype inherits from User.prototype:
Admin.prototype = Object.create(User.prototype);
The admin gets the inherited login() method:
admin.login();
It also has its own method:
admin.deleteUser("Aman");
The final prototype structure is:
admin
↓
Admin.prototype
↓
User.prototype
↓
Object.prototype
↓
null
This is a classic example of prototype-based inheritance.
Key Takeaways
- JavaScript uses prototype-based inheritance.
- Every ordinary JavaScript object has an internal prototype link, which can be inspected with
Object.getPrototypeOf(). - Constructor functions have a
prototypeproperty used when creating objects withnew. - Prototype methods can be shared by multiple objects.
Object.create()can create an object with a specified prototype.- The prototype chain is used when JavaScript cannot find a property directly on an object.
Object.prototypeis commonly near the end of the prototype chain for ordinary objects.nullmarks the end of a prototype chain.Object.getPrototypeOf()is preferred over the legacy__proto__accessor for inspecting prototypes.__proto__exists in many environments but should generally not be used as the primary way to work with prototypes.Constructor.prototypeand an object’s internal prototype are related but are not the same thing.Object.create(Parent.prototype)can be used to establish inheritance between constructor-function prototypes.Constructor.call(this, ...)can initialize properties from a parent constructor.constructormay need to be restored after replacing a child constructor’s prototype.- Prototype methods are shared rather than duplicated as separate function properties on every instance.
- ES6
classsyntax provides a cleaner way to express many inheritance patterns, while the underlying JavaScript model remains prototype-based.
FAQs
1. What is a prototype in JavaScript?
A prototype is an object that another object can use for property and method lookup.
For example:
const person = {
greet: function() {
console.log("Hello");
}
};
const student = Object.create(person);
Here, person acts as the prototype of student.
2. What is the prototype chain?
The prototype chain is the sequence of objects JavaScript checks when looking for a property or method.
For example:
object
↓
prototype
↓
Object.prototype
↓
null
If JavaScript cannot find a property on the object itself, it continues searching up the chain.
3. What is the difference between prototype and __proto__?
prototype is a property found on constructor functions and is used as the prototype for objects created with new.
__proto__ is a legacy accessor for an object’s internal prototype.
For example:
function Person() {}
const person = new Person();
console.log(Person.prototype);
console.log(Object.getPrototypeOf(person));
Both refer to the same prototype object in this example.
For modern code, prefer:
Object.getPrototypeOf(person);
4. Why are methods added to prototypes?
Adding shared methods to a prototype allows instances to use the same function instead of creating a separate function property for every instance.
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log("Hello");
};
Multiple Person objects can use the same greet() function.
5. What does Object.create() do?
Object.create() creates a new object and sets its prototype to the object supplied as its argument.
const person = {
greet() {
console.log("Hello");
}
};
const student = Object.create(person);
Now student can access the inherited greet() method.
6. How does prototype inheritance work with constructor functions?
A common pattern is:
Child.prototype = Object.create(Parent.prototype);
This makes Child.prototype inherit from Parent.prototype.
The child constructor can also call the parent constructor:
Parent.call(this, value);
Together, these establish both property initialization and prototype-based method inheritance.
7. Are JavaScript classes related to prototypes?
Yes. JavaScript classes use the prototype system underneath.
For example:
class Person {
greet() {
console.log("Hello");
}
}
The greet() method is available through Person.prototype.
So learning prototypes helps you understand how JavaScript classes and inheritance work internally.
Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.
