J

JavaScript Handbook

Clean • Professional

Object Prototypes & Inheritance in JavaScript

2 minute

Object Prototypes & Inheritance in JavaScript

In JavaScript, prototypes and inheritance form the foundation of the language’s object-oriented behavior. Every JavaScript object is linked to another object, called its prototype, from which it can inherit properties and methods.

This system is known as prototypal inheritance, and it allows objects to share behavior efficiently without duplicating code.

What is a Prototype?

A prototype is an object from which other objects inherit properties and methods.

Every JavaScript object has an internal link ([[Prototype]]) that points to another object — accessible through the special property __proto__ or via Object.getPrototypeOf().

Example:

const person = {
  greet() {
    console.log("Hello!");
  }
};

const student = Object.create(person);
student.study = function() {
  console.log("Studying...");
};

student.greet(); // Inherited from person -> "Hello!"
student.study(); // Own method -> "Studying..."

The Prototype Chain

When you access a property or method on an object:

  1. JavaScript first looks for it on the object itself.
  2. If not found, it looks up the prototype chain until it finds it or reaches null.

Example:

If the property isn’t found even at the top of the chain (Object.prototype), it returns undefined.

console.log(student.__proto__ === person); // true
console.log(Object.getPrototypeOf(student) === person); // true

Constructor Functions and Prototypes

Constructor functions use the prototype property to define shared methods.

Example:

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const alice = new Person("Alice");
alice.greet(); // "Hello, my name is Alice"

Inheritance with Constructor Functions

You can create inheritance using constructor functions and prototypes:

function Person(name) {
  this.name = name;
}
Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.name}`);
};

function Student(name, subject) {
  Person.call(this, name); // Inherit properties
  this.subject = subject;
}

// Inherit methods
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.study = function() {
  console.log(`${this.name} studies ${this.subject}`);
};

const bob = new Student("Bob", "Math");
bob.greet(); // "Hello, I'm Bob"
bob.study(); // "Bob studies Math"

Inheritance Using ES6 Classes (Modern Approach)

ES6 introduced classes as syntactic sugar over prototypes.

extends → sets up the prototype chain automatically

super() → calls the parent constructor

Example:

class Person {
  constructor(name) {
    this.name = name;
  }
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
}

class Student extends Person {
  constructor(name, subject) {
    super(name); // Calls parent constructor
    this.subject = subject;
  }
  study() {
    console.log(`${this.name} studies ${this.subject}`);
  }
}

const alice = new Student("Alice", "Physics");
alice.greet(); // "Hello, I'm Alice"
alice.study(); // "Alice studies Physics"

The Object Prototype Hierarchy

At the top of all JavaScript objects is Object.prototype, which provides built-in methods like:

  • hasOwnProperty()
  • toString()
  • valueOf()

Example:

console.log(Object.getPrototypeOf({}) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype)); // null

Advantages of Prototypal Inheritance

  • Memory-efficient (methods shared across objects)
  • Dynamic (new properties can be added at runtime)
  • Flexible (supports object-to-object linking)

Article 0 of 0