Understanding JavaScript Prototype Chains and Inheritance

JavaScript's Inheritance Design

JavaScript's inheritance model operates through prototype chains rather than classical class-based inheritance. When Netscape needed a scripting language for web interactivity in 1994, Brendan Eich designed a system where objects inherit directly from other objects.

In classical languages like Java, inheritance works through classes:

class Animal {
    void eat() { System.out.println("Eating"); }
}

class Dog extends Animal {
    void bark() { System.out.println("Barking"); }
}

JavaScript achieves similar functionality through constructor functions and prototypes:

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");
};

Prototype Mechanism

Every JavaScript fucntion has a prototype property, and every object has a [[Prototype]] internal slot (accessible via __proto__ in many environments).

When you create an object using a constructor functon:

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

const person = new Person("Alice");

The relationship is established where person.__proto__ === Person.prototype.

Property lookup follows the prototype chain:

Person.prototype.species = "Homo sapiens";

console.log(person.name);    // "Alice" - found on instance
console.log(person.species); // "Homo sapiens" - found on prototype
console.log(person.age);     // undefined - not found in chain

The lookup proceeds: instance → Person.prototype → Object.prototype → null.

Constructor Property

Each prototype object has a constructor property pointing back to its constructor funcsion:

console.log(Person.prototype.constructor === Person); // true
console.log(person.constructor === Person);           // true

Modern Class Syntax

ES6 introduced class syntax as syntactic sugar over prototype-based inheritance:

class Vehicle {
    constructor(type) {
        this.type = type;
    }
    
    move() {
        console.log(this.type + " is moving");
    }
}

class Car extends Vehicle {
    constructor(model) {
        super("car");
        this.model = model;
    }
    
    honk() {
        console.log(this.model + " is honking");
    }
}

This translates to essentially the same prototype chain structure.

Performance Considerations

Prototype chain traversal can impact performance when searching for properties deep in the chain. Use hasOwnProperty to check for direct properties:

const obj = { prop: "value" };

console.log(obj.hasOwnProperty("prop"));     // true
console.log(obj.hasOwnProperty("toString")); // false - inherited

Modern JavaScript provides Object.hasOwn as a safer alternative:

console.log(Object.hasOwn(obj, "prop"));     // true

Prototype Pollution Security

Modifying prototypes can lead to security vulnerabilities when attacker-controlled data affects object inheritance:

const user1 = { isAdmin: false };

// Malicious code modifies Object.prototype
Object.prototype.isAdmin = true;

const user2 = {};
console.log(user2.isAdmin); // true - polluted through prototype

Common attack vectors include unsafe merge operations:

function unsafeMerge(target, source) {
    for (const key in source) {
        target[key] = source[key];
    }
}

const config = {};
const maliciousInput = JSON.parse('{"__proto__": {"isAdmin": true}}');

unsafeMerge(config, maliciousInput);

const newUser = {};
console.log(newUser.isAdmin); // true - prototype polluted

Safe practices include using Object.create(null) for prototype-less objects and validating inputs.

Prototype Chain Nature

The prototype chain is fundamentally a lookup mechanism rather than a specific data structure. It enables JavaScript's prototypal inheritance system by linking objects through their prototype references.

Tags: javascript Prototype Inheritance object-oriented programming

Posted on Wed, 29 Jul 2026 16:09:15 +0000 by jsinker