📡 You're offline — showing cached content
New version available!
Quick Access
JavaScript Intermediate

JavaScript Prototype and Inheritance Explained Simply

Understand JavaScript prototype chain, constructor functions, ES6 classes, and how inheritance works under the hood with clear examples.

EzyCoders Admin January 20, 2026 10 min read 1 views
JavaScript Prototype and Inheritance Guide
Share: Twitter LinkedIn WhatsApp

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.

EzyCoders Admin
Written by
EzyCoders Admin

Team Lead and Full-Stack Developer with experience in PHP, JavaScript, SQL, DSA, and System Design. Passionate about software engineering, scalable web technologies, and helping developers prepare for coding interviews and tech careers through practical tutorials and professional guidance.

Comments (0)

No comments yet. Be the first!

Leave a Comment