JavaScript Mastery: From Fundamentals to Modern ES2024+
HomeInsightsCoursesJavaScriptPrototypal Inheritance
OOP & Inheritance

Prototypal Inheritance

JavaScript does not use traditional class-based inheritance like Java or C++. Instead, it uses Prototypes—a chain of linked objects that allow for sophisticated behavior sharing and exceptional memory efficiency.

The Prototype Chain

Every object in JavaScript has a internal link to another object called its Prototype. When you access a property that doesn't exist on the object, the engine "walks up" this chain until it finds the property or hits null.

JAVASCRIPT
// The Prototype Chain in action
const hardware = {
    brand: 'NVIDIA',
    type: 'GPU',
    specs() {
        return `${this.brand} ${this.type}`;
    }
};

const vRAM = {
    size: '24GB',
    // Setting inheritance via Object.create
    __proto__: hardware
};

console.log(vRAM.size);  // '24GB' (Own Property)
console.log(vRAM.brand); // 'NVIDIA' (Inherited via Chain)
console.log(vRAM.specs()); // 'NVIDIA GPU' (Inherited Method)

Memory Efficiency: Prototype vs Instance

Understanding prototypes is crucial for performance. Methods added to a function's prototype are shared across all instances. Methods added inside a constructor are duplicated for every single instance, consuming significantly more memory.

JAVASCRIPT
// --- Prototype vs Instance Methods ---

function OptimizedObject(id) {
    this.id = id;
}

// ✅ Memory Efficient: All instances share 1 function reference
OptimizedObject.prototype.logId = function() {
    console.log(this.id);
};

function InefficientObject(id) {
    this.id = id;
    // ❌ Memory Leak: Every instance gets a custom function clone
    this.logId = function() {
        console.log(this.id);
    };
}
💡 Architect's Rule: Use the prototypefor methods (behavior) and the constructor for instance-specific data (state).

The Pure Object Pattern

Sometimes you need a hash map that is completely empty, without built-in methods like toString or hasOwnProperty. This prevents Prototype Pollution attacks where an attacker might overwrite shared methods.

JAVASCRIPT
// Object.create(null) - The High Performance Dictionary
const dictionary = Object.create(null);

// Standard objects have inherited methods like .toString()
console.log({}.toString); // [Function: toString]

// A null prototype object is "Pure" - no inheritance risk
console.log(dictionary.toString); // undefined

// 💡 Ideal for maps where you don't want property pollution.

__proto__ vs .prototype

This is the most common point of confusion in JavaScript. The prototype property is used by Constructor Functions to set the prototype of new instances. The __proto__ property is the actual link on the instance itself.

JAVASCRIPT
// How 'new' actually works under the hood
function User(name) {
    this.name = name;
}

const u1 = new User('Alice');

/* 
  1. {} is created
  2. {}.__proto__ = User.prototype
  3. User.call({}, 'Alice')
  4. The object is returned
*/

console.log(u1.__proto__ === User.prototype); // true
In modern development, we use Object.getPrototypeOf()instead of __proto__ for better performance and compatibility.

Technical Recap:

  • ✅ Hierarchy: Most objects eventually trace back to Object.prototype.
  • ✅ Shadowing: If an object has its own property with the same name as a prototype property, it "shadows" it.
  • ✅ Efficiency: Use prototypes to prevent creating 10,000 function instances for 10,000 objects.
  • ❌ Mutation: Modifying Object.prototype is a major anti-pattern that can break entire libraries.
  • ✅ Modernity: ES6 Classes use this exact system under the hood; prototypes are the engine, Classes are the dashboard.

What's Next?

Now that you've mastered the underlying engine of inheritance, let's look at the clean, modern syntax: ES6 Classes.