Skip to Content
Course content

68: Prototypal Inheritance Explained

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've spent a lot of time reviewing code for junior devs, and there is one mistake that comes up almost every single time we hit the topic of inheritance: the belief that when an object "inherits" a method, that method is actually copied onto the new object.

"Inheritance is just copying methods from a parent"

It seems intuitive, right? You create a base class, you create a subclass, and you assume the subclass now "owns" those methods. Let's look at why that's fundamentally wrong. If JavaScript actually copied methods, we'd be wasting a massive amount of memory by duplicating the same function thousands of times across thousands of objects.

const GameCharacter = {
  greet() {
    console.log(`Hello, I am ${this.name}`);
  }
};

const warrior = Object.create(GameCharacter);
warrior.name = "Thorin";

warrior.greet(); // "Hello, I am Thorin"

At first glance, it looks like warrior has a greet method. But if you check warrior.hasOwnProperty('greet'), it returns false. The method isn't there. So where is it? This is where the "magic" (which is actually just a linked list) happens.

The Prototype Chain is a lookup, not a copy

When you call warrior.greet(), JavaScript doesn't just give up if it doesn't find the method on the warrior object. Instead, it says, "Okay, it's not here. Let me check the object's internal prototype link."

It follows that link to GameCharacter, finds the greet function there, and executes it. I like to think of it as a corporate hierarchy: if a junior employee doesn't know how to handle a request, they ask their manager. If the manager doesn't know, they ask the director. The request keeps moving up the chain until someone knows the answer or they hit the very top (Object.prototype) and finally return undefined.

Here is the concrete proof that no copying is happening. Watch what happens if we add a method to the parent after the child has already been created:

const GameCharacter = {
  greet() {
    console.log(`Hello, I am ${this.name}`);
  }
};

const warrior = Object.create(GameCharacter);
warrior.name = "Thorin";

// We add a new method to the parent AFTER the warrior was created
GameCharacter.attack = function() {
  console.log(`${this.name} swings a sword!`);
};

warrior.attack(); // "Thorin swings a sword!"

If JavaScript had copied the methods during Object.create(), the warrior would have no idea that attack exists. But because it's a live link, the warrior finds the new method instantly. This is the essence of prototypal inheritance.

You've probably seen the class keyword in modern JS. Just remember: class is "syntactic sugar." Under the hood, JavaScript is still doing exactly this—linking objects via prototypes. It's not like Java or C#; there are no "blueprints" being stamped out, only objects linking to other objects.

  • Own Properties: Things defined directly on the object (like warrior.name).
  • Inherited Properties: Things found further up the prototype chain (like warrior.greet).
  • The Chain: The path from the object $\rightarrow$ its prototype $\rightarrow$ its prototype's prototype $\rightarrow$ null.



📋 Practical Task

Building a Prototypal RPG Item System

Your goal is to create a prototype chain for a game's item system. Instead of using the class keyword, you will use Object.create() to demonstrate your understanding of the prototype chain.

Requirements:

  • Create a base object called Item. It should have a method inspect() that logs: "This is a [name] with a value of [value] gold."
  • Create a second object called Weapon that inherits from Item. Weapon should have a method attack() that logs: "[name] deals [damage] damage!"
  • Create a specific instance called excalibur that inherits from Weapon. Give it the following own properties: name: "Excalibur", value: 1000, and damage: 50.

Verification:

When you call excalibur.inspect(), it should successfully find the method on the Item object. When you call excalibur.attack(), it should find it on the Weapon object. Finally, verify that excalibur.hasOwnProperty('inspect') returns false.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.