Ticker

6/recent/ticker-posts

🧬 JavaScript Prototypes & Prototypal Inheritance — How Objects Really Work

🧬 JavaScript Prototypes & Prototypal Inheritance — How Objects Really Work

Prototypes sound scary until you realize you’ve been using them since day one.

Every array method, every string function, every object method you call — that’s prototype magic in action.
Once you understand how JavaScript links objects together, a lot of “weird” behavior suddenly makes sense.

This was one of those topics that only truly clicked for me after debugging a method that “disappeared” from an object. Spoiler: it was on the prototype the whole time.

🧠 The Prototype Chain

Every JavaScript object has a hidden link to another object called its prototype.

When you access a property:

user.toString();

JavaScript looks:

  1. On user
  2. Then on user’s prototype
  3. Then on that prototype’s prototype
  4. …until it finds it or hits null

That lookup path is the prototype chain.

🧱 Creating Objects With Prototypes

const animal = {
  eat() {
    return "eating...";
  }
};

const dog = Object.create(animal);

dog.eat(); // "eating..."

dog doesn’t have eat() directly — it finds it through its prototype.

This is prototypal inheritance in action.

🏗️ Constructor Functions (The Old-School Way)

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

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

const sam = new User("Sam");
sam.greet(); // "Hi, I'm Sam"

Methods on the prototype are shared between instances — this is memory-efficient and fast.

🧩 Classes Are Just Prototypes in Disguise

class User {
  constructor(name) {
    this.name = name;
  }

  greet() {
    return `Hi, I'm ${this.name}`;
  }
}

Under the hood, this still uses prototypes.
Classes just give us cleaner syntax and fewer footguns.

🚨 Common Mistakes Developers Actually Make

❌ Adding methods inside constructors

function User(name) {
  this.greet = function () { ... }; // duplicated per instance
}

This wastes memory. Put shared methods on the prototype.

❌ Modifying built-in prototypes

Array.prototype.last = function () { ... }; // ❌

This can break libraries and future JavaScript features.

❌ Confusing own properties vs prototype properties

sam.hasOwnProperty("greet"); // false

Knowing where a property lives helps with debugging.

🧪 Advanced Insight: Shadowing Prototype Properties

const base = { x: 1 };
const obj = Object.create(base);

obj.x = 2;

console.log(obj.x);  // 2
console.log(base.x); // 1

The property on obj shadows the prototype property.
This can be powerful — or confusing — depending on how intentional you are.

From experience: shadowing is the root cause of many “why didn’t this change everywhere?” bugs.

🎯 Final Thoughts

JavaScript doesn’t copy behavior between objects — it links them.

Once you internalize that mental model, prototypes stop being mysterious and start feeling like a powerful, simple foundation for how the language works.

🚀 Best Practice Summary

✅ Prefer class syntax for clarity
✅ Put shared methods on prototypes
✅ Avoid mutating built-in prototypes
✅ Understand the prototype chain for debugging
✅ Be mindful of property shadowing

Reactions

Post a Comment

0 Comments