DEV Community

Cover image for Prototype Pattern in JavaScript
Md Enayetur Rahman
Md Enayetur Rahman

Posted on

Prototype Pattern in JavaScript

A practical guide inspired by “Learning Patterns” by Lydia Hallie & Addy Osmani

Patterns.dev describes the Prototype Pattern as a way to “share properties among many objects of the same type.” Instead of duplicating methods on every instance, JavaScript lets objects inherit from a shared prototype so they can find behavior up the chain.


1. Why prototypes?

When you need hundreds or thousands of similar objects, copying the same functions into each one wastes memory. By placing shared behavior on the prototype, every instance has one reference to that function instead of its own copy.

“The prototype pattern is a useful way to share properties among many objects of the same type… avoiding duplication of methods and properties, thus reducing the amount of memory used.” — Learning Patterns


2. A first example: Dogs that bark

class Dog {
  constructor(name) {
    this.name = name;      // unique per instance
  }

  bark() {                 // lives on Dog.prototype
    return `${this.name} says woof!`;
  }
}

const fido = new Dog("Fido");
console.log(fido.bark());            // "Fido says woof!"
console.log(fido.__proto__ === Dog.prototype); // true
Enter fullscreen mode Exit fullscreen mode

All Dog instances share one bark method on Dog.prototype. Whenever JavaScript can’t find bark directly on fido, it looks up the prototype chain until it does.


3. Adding behavior after the fact

Dog.prototype.play = function () {
  return `${this.name} is playing!`;
};

console.log(fido.play()); // "Fido is playing!"
Enter fullscreen mode Exit fullscreen mode

Because every dog points to the same prototype, they all “magically” learn to play() at runtime—without recreating or mutating individual instances.


4. Extending the chain: SuperDog

class SuperDog extends Dog {
  fly() {
    return `${this.name} takes off! ✈️`;
  }
}

const daisy = new SuperDog("Daisy");
console.log(daisy.bark()); // inherited
console.log(daisy.fly());  // new ability
Enter fullscreen mode Exit fullscreen mode

The prototype chain now looks like:

daisy → SuperDog.prototype → Dog.prototype → Object.prototype → null
Enter fullscreen mode Exit fullscreen mode

JavaScript walks the chain until it finds each requested property.


5. Object.create for direct delegation

Sometimes a full class is overkill—you just want one object to delegate to another.

const dog = { bark() { return "woof"; } };
const pet1 = Object.create(dog);   // prototype = dog

console.log(pet1.bark());          // "woof"
Enter fullscreen mode Exit fullscreen mode

Object.create(proto) sets proto as the new object’s prototype, letting you build ad‑hoc delegations on the fly.


6. When to reach for the Prototype Pattern

Use‑case Why prototypes help
Many identical objects Reuse the same functions, save memory
Post‑creation patches Add methods once, all instances get them
Classical inheritance Extend prototypes to build chains of behavior
Flyweight objects Share heavy data across millions of instances

Tip: Don’t mutate built‑in prototypes (Array.prototype, String.prototype) in production code—it leads to “prototype pollution” and hard‑to‑track bugs.


7. Trade‑offs

Pros

  • Memory‑efficient sharing of behavior
  • Dynamic: you can augment prototypes after instances exist
  • Mimics “classical” inheritance, easing mental models

⚠️ Cons

  • Overusing inheritance can create deep, fragile chains
  • Prototype pollution can leak globals if not careful
  • Modern ES6+ modules and composition often replace inheritance patterns

Conclusion

The Prototype Pattern is baked into JavaScript’s DNA. By understanding how objects delegate along the prototype chain, you can write code that’s both memory‑efficient and flexible—without reinventing classes or copying functions everywhere.

Next in the series we’ll explore Flyweight Pattern for crushing memory use in huge data sets—stay tuned for #LearningPatterns21!


This post is part of my “Learning Patterns” series. Follow the hash *#LearningPatterns** to catch every installment.*

Top comments (0)