Prototypes

How objects inherit from other objects. The foundation of JavaScript OOP.

What Are Prototypes?

Every object has a hidden link to another object it inherits from.

const dog = {
  bark() { return "Woof!"; }
};

const myDog = Object.create(dog);
myDog.name = "Rex";

myDog.name;  // "Rex" (own property)
myDog.bark(); // "Woof!" (inherited from dog!)

// myDog doesn't have bark() itself
// but it has a PROTOTYPE LINK to dog
// JavaScript follows the link to find bark()

myDog

name: "Rex"

[[Prototype]]→→→

dog

bark: ƒ

[[Prototype]]→→→

Object.prototype

toString, etc.

__proto__ vs .prototype

Two different things with confusing names.

__proto__ (or [[Prototype]])

  • • Every object has it
  • • Points to its parent
  • • Used for property lookup
  • • Access: Object.getPrototypeOf(obj)

.prototype (property)

  • • Only functions have it
  • • Template for instances
  • • Becomes __proto__ of new objects
  • • Access: Function.prototype
function Person(name) {
  this.name = name;
}
Person.prototype.greet = function() {
  return "Hi, I'm " + this.name;
};

const alice = new Person("Alice");

// alice.__proto__ === Person.prototype  → true!
// Person.prototype is the TEMPLATE
// alice.__proto__ is the LINK to that template

Object.create()

Create an object with a specific prototype.

// Object.create(proto) — clean prototype inheritance:
const animal = {
  alive: true,
  eat() { return "eating"; },
};

const cat = Object.create(animal);
cat.name = "Whiskers";
cat.meow = function() { return "Meow!"; };

cat.name;  // "Whiskers" (own)
cat.meow(); // "Meow!" (own)
cat.eat();  // "eating" (inherited from animal)
cat.alive;  // true (inherited)

// Object.create(null) — no prototype at all:
const bare = Object.create(null);
bare.toString; // undefined (no Object.prototype!)

Constructor Functions

The pre-class way to create objects with shared methods.

function Car(make, model) {
  // 'new' creates an empty object and sets 'this'
  this.make = make;
  this.model = model;
}

// Shared methods go on .prototype:
Car.prototype.describe = function() {
  return `${this.make} ${this.model}`;
};

const tesla = new Car("Tesla", "Model 3");
tesla.describe(); // "Tesla Model 3"

Constructor functions + 'new' create objects. Methods on .prototype are shared (not copied) between all instances.

💡 'new' does: create obj, set __proto__, call function, return obj
1 / 3

Property Lookup

How JavaScript searches for a property.

const parent = { x: 1, y: 2 };
const child = Object.create(parent);
child.z = 3;

// Lookup for child.z:
// 1. Check child itself → found! z = 3 ✓

// Lookup for child.x:
// 1. Check child itself → not found
// 2. Check child.__proto__ (parent) → found! x = 1 ✓

// Lookup for child.toString:
// 1. Check child → not found
// 2. Check parent → not found
// 3. Check Object.prototype → found! ✓

// Lookup for child.foo:
// 1. child → ✗  2. parent → ✗  3. Object.prototype → ✗
// 4. null (end of chain) → undefined

Key points:

  • Own properties shadow (override) inherited ones
  • Writing a property always creates it on the object itself
  • hasOwnProperty() checks only own, not inherited
  • in operator checks both own and inherited

FAQ

Common questions about prototypes.