Prototypes: What Classes Really Are

Sophomore Year, page 8 of 11. A two-minute read.

Here's a secret that Professor Semicolon has been dying to tell you.

JavaScript didn't have classes until 2015. Before that, people still did object-oriented programming, using something called prototypes. And here's the twist: classes are mostly just nicer syntax on top of prototypes. Under the hood, they're still prototypes.

Every object in JavaScript has a hidden link to another object, called its prototype. When you ask an object for a property it doesn't have, JavaScript doesn't give up straight away. It follows the link and looks in the prototype. If it's not there, it looks in the prototype's prototype, and so on up the prototype chain, until it finds the property or runs out of prototypes.

JavaScript
class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    return `${this.name} makes a sound.`;
  }
}

const cat = new Animal("Whiskers");

console.log(Object.keys(cat));
console.log(Object.getPrototypeOf(cat) === Animal.prototype);
console.log(Object.getOwnPropertyNames(Animal.prototype));
console.log(typeof Animal);

It prints

[ 'name' ]
true
[ 'constructor', 'speak' ]
function

Look at that! The cat object itself only has one property: name. The speak method isn't stored on the cat at all. It lives on Animal.prototype, which is the cat's prototype. When you call cat.speak(), JavaScript doesn't find speak on cat, follows the link to Animal.prototype, finds it there, and runs it with this set to cat.

This is actually very efficient. If you create a million cats, there's still only one copy of speak, shared by all of them through the prototype. And notice that typeof Animal is "function". A class is really a special kind of function!

This also explains how every array has methods like map and push: they live on Array.prototype, which every array links to. And it's how inheritance works: Wizard.prototype links to Character.prototype, so wizards can find Character methods by following the chain.

Note

You don't need to work with prototypes directly in modern code. Classes are the way to go. But knowing that prototypes exist will help you understand error messages, older code, and documentation (MDN talks about Array.prototype.map, for example, which simply means "the map method that all arrays share").

Reading is step one

CurlyScript turns these notes into a game: short questions, an explanation after every answer, and a test at the end of each grade. Free, with nothing to sign up for.

Start learning