We all know what an object is in JavaScript, right?

A good ol' data structure that lets you store key-value pairs.

const user = {
  name: "Alice",
  age: 28,
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
};

Simple. Clean. Works.

But have you ever wondered:

How is it that every object can use methods like toString() even if you didn’t define them?

Try this:

console.log(user.toString); // [Function: toString]

Wait a minute. You never wrote toString in your user object.

So… where’s it coming from?

Enter the World of Prototypes

In JavaScript, every object has a hidden property called [[Prototype]] (you can think of it as a secret link to another object).

That link points to another object, which we lovingly call the prototype.

In modern JavaScript, you can see it via __proto__:

console.log(user.__proto__);

Image description

This prototype object is like a blueprint or a backup storage.

If JavaScript doesn’t find a property in the object itself, it’ll go check the prototype.

Still not there? It’ll go up the chain again.

This chain of looking-up is called the prototype chain.

Object Prototypes: A Real Example

Let’s build our own:

const animal = {
  speak() {
    console.log("Animal sound");
  }
};

const dog = {
  name: "Charlie",
  __proto__: animal
};

dog.speak();

Image description

We never defined speak() inside dog, but it still works — because it found it in animal, the prototype.

Think of it like dog saying:

“I don’t have a speak method... but let me ask my prototype real quick.”

Behind the Scenes

When you create an object using literal syntax {}, it automatically gets a prototype:

const empty = {};
console.log(empty.__proto__ === Object.prototype);

This Object.prototype is the grandparent of all objects — the final stop in the chain.

Image description

Function Prototypes vs Object Prototypes

Another curveball: Functions in JavaScript also have a prototype property.

But hold up — this one’s for when you use them as constructors:

function Car() {}
Car.prototype.drive = function () {
  console.log("Vroom!");
};

const myCar = new Car();
myCar.drive();

Image description

So:

  • Car.prototype is what new objects created with new Car() will link to.
  • myCar.__proto__ === Car.prototype is true.

Why Care?

Understanding prototypes helps you:

  • Build cleaner inheritance models
  • Avoid duplicating methods across objects
  • Know what’s really going on when you write Object.create(), or use class in modern JS

Plus, you’ll look super smart in code reviews 😎

TL;DR

  • Every object in JS has a prototype
  • If a property isn’t found, JS checks the prototype (and its prototype, etc.)
  • Functions have a special prototype used for instances created with new
  • It’s how inheritance works in JS

Next time someone drops the phrase “prototype chain,” you’ll be like,

“Been there, walked the chain.”

Want to go deeper? I can write a follow-up on how ES6 classes use prototypes under the hood.


I’ve been actively working on a super-convenient tool called LiveAPI.

LiveAPI helps you get all your backend APIs documented in a few minutes

With LiveAPI, you can quickly generate interactive API documentation that allows users to execute APIs directly from the browser.

Image description

If you’re tired of manually creating docs for your APIs, this tool might just make your life easier.