🧬 JavaScript Object Prototypes

In JavaScript, every object has a hidden internal property called [[Prototype]], which refers to another object. This object is known as the prototype.

The prototype is used for inheritance: if a property or method is not found on the object itself, JavaScript looks for it in the prototype, and continues up the chain until it finds it—or reaches the end (null).


🔹 Why Use Prototypes?

Prototypes allow JavaScript to:

  • Share methods and properties across all instances of a constructor
  • Save memory (methods are not duplicated per instance)
  • Implement inheritance in a flexible, object-based way

🔹 How It Works: A Simple Example

javascriptCopyEditconst person = {
  greet() {
    console.log("Hello!");
  }
};

const user = Object.create(person);
user.name = "Alice";

user.greet(); // "Hello!"

Explanation:

  • user does not have a greet() method.
  • JavaScript looks into user‘s prototype (person) and finds greet().

🔹 The Prototype Chain

javascriptCopyEdituser → person → Object.prototype → null

JavaScript walks up this prototype chain when accessing properties or methods.


🔹 Constructor Functions and Prototypes

When you create objects using constructor functions, you can attach methods to the constructor’s prototype so all instances share them.

javascriptCopyEditfunction Person(name) {
  this.name = name;
}

// Add method to prototype
Person.prototype.sayHello = function () {
  console.log("Hi, I'm " + this.name);
};

const alice = new Person("Alice");
const bob = new Person("Bob");

alice.sayHello(); // "Hi, I'm Alice"
bob.sayHello();   // "Hi, I'm Bob"

Here, both alice and bob share the same sayHello method from Person.prototype.


🔹 Class Syntax (ES6) — Under the Hood

ES6 introduced the class syntax, but it still uses prototypes behind the scenes.

javascriptCopyEditclass Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a sound.`);
  }
}

const dog = new Animal("Rex");
dog.speak(); // "Rex makes a sound."

Under the hood:

  • Animal.prototype.speak is created.
  • dog.__proto__ === Animal.prototype is true.

🔍 Inspecting Prototypes

You can inspect or interact with prototypes using:

  • Object.getPrototypeOf(obj)
  • obj.__proto__ (legacy but commonly used)
  • Object.setPrototypeOf(obj, proto)

Example:

javascriptCopyEditconsole.log(Object.getPrototypeOf(dog) === Animal.prototype); // true

🧠 Inheritance with Prototypes

JavaScript allows inheritance via prototypes:

javascriptCopyEditfunction Vehicle(type) {
  this.type = type;
}

Vehicle.prototype.describe = function () {
  console.log(`This is a ${this.type}.`);
};

function Car(brand) {
  Vehicle.call(this, "car");
  this.brand = brand;
}

// Inherit from Vehicle
Car.prototype = Object.create(Vehicle.prototype);
Car.prototype.constructor = Car;

Car.prototype.honk = function () {
  console.log(`${this.brand} says beep!`);
};

const myCar = new Car("Toyota");
myCar.describe(); // "This is a car."
myCar.honk();     // "Toyota says beep!"

📝 Summary Table

ConceptDescription
prototypeProperty of constructor functions
__proto__Property of objects pointing to their prototype
InheritanceAchieved by walking the prototype chain
EfficiencyMethods are shared via prototypes

✅ Conclusion

Prototypes are the backbone of inheritance in JavaScript. While newer syntax like class makes things more readable, understanding how prototypes work under the hood helps you:

  • Debug tricky inheritance bugs
  • Optimize memory by sharing methods
  • Work with frameworks and tools that rely on prototypal inheritance