Constructor/Prototype Pattern in JavaScript

📌 What is the Constructor/Prototype Pattern?

The Constructor/Prototype Pattern is a common way to create multiple object instances that share behavior efficiently in JavaScript. This pattern separates instance-specific data (via constructor) and shared methods (via prototype). 🧠

Note

This pattern combines the advantages of both constructor functions and prototypes, making it memory-efficient and object-oriented.

👷 The Constructor Function

A constructor function initializes properties unique to each object:

Basic Constructor

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Here, name and age are stored on each individual object created with new.

🧬 Adding Methods via Prototype

Instead of adding methods directly in the constructor (which would create a new copy for every instance), we add them to the constructor’s prototype:

Constructor/Prototype Pattern Example

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function () {
  console.log("Hello, my name is " + this.name);
};

const user1 = new Person("Alice", 30);
const user2 = new Person("Bob", 25);

user1.sayHello(); // Hello, my name is Alice
user2.sayHello(); // Hello, my name is Bob

✅ Both user1 and user2 share the same sayHello function from the prototype. Efficient and elegant!

🔎 Behind the Scenes

When you call user1.sayHello(), JavaScript:

  • Looks for sayHello on user1
  • Doesn’t find it — climbs up to Person.prototype
  • Executes the shared method 🎯

💡 Why Use This Pattern?

  • Memory Efficient: All instances share methods instead of duplicating them.
  • Separation of Concerns: Instance data vs. shared behavior.
  • OOP-Friendly: Emulates classical inheritance structure using prototypes.

🛠️ Custom Methods and Inheritance

You can build more complex object hierarchies by chaining constructors and prototypes:

Inheritance with Constructor/Prototype

function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function () {
  console.log(this.name + " makes a noise.");
};

function Dog(name, breed) {
  Animal.call(this, name); // Call parent constructor
  this.breed = breed;
}

// Inherit from Animal
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.bark = function () {
  console.log(this.name + " barks.");
};

const rex = new Dog("Rex", "German Shepherd");
rex.speak(); // Rex makes a noise.
rex.bark();  // Rex barks.

🧩 Summary

  • Use constructor functions to initialize instance-specific properties.
  • Use prototype to define shared methods once for all instances.
  • This pattern promotes memory efficiency and maintainability.

📚 Further Reading

>>“Prototypes let you shape the blueprint. Constructors let you fill in the blanks.” — JavaScript Philosophy 🔧