JavaScript Prototypes and Inheritance Practice Questions with Solutions

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 prototype property used when creating objects with new.
  • 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.prototype is commonly near the end of the prototype chain for ordinary objects.
  • null marks 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.prototype and 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.
  • constructor may 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 class syntax 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.

Scroll to Top