Skip to main content

Prototypes & Inheritance Mechanics

Unlike traditional class-based object-oriented languages like Java or C++, JavaScript uses Prototypal Inheritance. Every JavaScript object possesses an internal link to another object called its Prototype, forming a chain used for property and method resolution.

The Prototype Chain

When you attempt to access a property or method on an object, the JavaScript engine follows a strict lookup procedure:

Prototype Resolution Chain
┌──────────────────────────────────────────────┐
│ myObject │
│ └─ [[Prototype]] -> DeveloperPrototype │
│ └─ [[Prototype]] -> Object.prototype │
│ └─ [[Prototype]] -> null │
└──────────────────────────────────────────────┘

  1. Checks if the property exists directly on myObject (an own property).
  2. If missing, traverses up the internal [[Prototype]] link.
  3. Continues climbing until it finds the property or reaches Object.prototype.[[Prototype]], which is null.
  4. Returns undefined if the property is unfound anywhere along the chain.

prototype Property vs. __proto__

A common source of confusion in JavaScript is the distinction between Function.prototype and Object.__proto__.

EntityDescriptionWhere It Exists
prototypeBlueprint object assigned to instances created via new.Exists only on Functions / Classes
__proto__Historic getter/setter exposing an object's internal [[Prototype]].Exists on all Objects
Object.getPrototypeOf()Modern standard method to access an object's prototype.Built-in static method
prototype-vs-__proto__.js
function User(name) {
this.name = name;
}

User.prototype.sayHello = function () {
return `Hello, I'm ${this.name}`;
};

const alex = new User("Alex");

console.log(alex.__proto__ === User.prototype); // true
console.log(Object.getPrototypeOf(alex) === User.prototype); // true

Prototypal vs. Class-Based Syntax

ES6 introduced the class keyword. However, JavaScript classes are primarily syntactic sugar over the existing prototypal system—under the hood, functions and prototypes still power everything.

Prototypal Delegation Pattern

prototypal-delegation.js
const animalActions = {
eat() {
return `${this.name} is eating.`;
}
};

// Create object linked directly to animalActions
const dog = Object.create(animalActions);
dog.name = "Rex";

console.log(dog.eat()); // "Rex is eating."

Modern ES6 Class Syntax

es6-class-syntax.js
class Animal {
constructor(name) {
this.name = name;
}

eat() {
return `${this.name} is eating.`;
}
}

class Dog extends Animal {
constructor(name, breed) {
super(name); // Call parent constructor
this.breed = breed;
}

bark() {
return `${this.name} barks loudly!`;
}
}

const rex = new Dog("Rex", "German Shepherd");
console.log(rex.eat()); // "Rex is eating." (Inherited from Animal)
console.log(rex.bark()); // "Rex barks loudly!"

Interactive Playground: Prototypal Chain Lookup

Inspect prototype linkage, property shadows, and method overrides in real time:

Prototypes in Action
JavaScript Runtime
Console Output

Best Practices

  1. Use ES6 Class Syntax for Readability: Prefer class and extends for clean OOP structures, but remember it uses prototypes underneath.
  2. Avoid Modifying Native Prototypes: Do not extend built-in objects like Array.prototype or Object.prototype (monkey patching), as it causes collisions with third-party libraries.
  3. **Use Object.getPrototypeOf()**: Avoid using the legacy __proto__ accessor in production code; use standard methods like Object.getPrototypeOf() and Object.setPrototypeOf().

Knowledge Check

Exercise Requirements:

  1. Implement a constructor function or class Shape that accepts color.
  2. Extend Shape with a Rectangle subclass that accepts color, width, and height, and includes a method getArea().
solution.js
class Shape {
constructor(color) {
this.color = color;
}
}

class Rectangle extends Shape {
constructor(color, width, height) {
super(color);
this.width = width;
this.height = height;
}

getArea() {
return this.width * this.height;
}
}

const rect = new Rectangle("blue", 10, 5);
console.log(`Color: ${rect.color}, Area: ${rect.getArea()}`); // Color: blue, Area: 50

Next Up

Now that you have mastered prototype delegation and class mechanics, proceed to Execution Context and Call Stack!