Skip to content
The Prototype Chain
step 1/7

Reading — step 1 of 7

Learn

~3 min readObjects in Depth

JavaScript's inheritance model is prototypal, not classical. Even after ES6 classes were added, classes are still syntactic sugar over the prototype mechanism. Understanding the chain is what separates intermediate from senior JavaScript developers — and it's how instanceof, polyfills, mixins, and weird debugger output finally make sense.

What's a prototype?

Every object in JavaScript has an internal [[Prototype]] link to another object — its prototype. When you read a property that doesn't exist on the object itself, JavaScript walks up the chain looking for it.

js

Object.create(proto) makes a new object with proto as its prototype. The new object has NO own properties — everything comes from the chain.

You can inspect the chain with Object.getPrototypeOf(obj) or the (legacy but widely supported) obj.__proto__.

Classes are sugar

js

Under the hood:

  • rex is an instance — its OWN properties are just name.
  • rex.__proto__ === Dog.prototype — has bark.
  • Dog.prototype.__proto__ === Animal.prototype — has eat.
  • Animal.prototype.__proto__ === Object.prototype — has toString, hasOwnProperty, etc.
  • Object.prototype.__proto__ === null — top of the chain.

The chain: rex → Dog.prototype → Animal.prototype → Object.prototype → null.

Method calls walk the chain

When you call rex.eat():

  1. JavaScript checks rex for eat — not found.
  2. Walks to Dog.prototype — not found.
  3. Walks to Animal.prototype — found! Calls it with this = rex.

That's how inherited methods work. The methods live on the prototype; instances share them.

instanceof walks the chain

js

x instanceof C checks: "is C.prototype somewhere in x's prototype chain?"

Why methods on the prototype

The prototype is shared across all instances:

js

If each instance had its own copy of bark, you'd waste memory. The prototype chain shares methods across all instances.

Class fields vs prototype methods

Modern class syntax has two ways to define methods:

js

Class fields (with =) are PER-INSTANCE. They don't share. Useful when you need bound this (arrow methods), but more memory.

Common mistakes

  • Modifying Object.prototype — affects EVERY object in the program. Practically always a bug.
  • Forgetting super(...) in subclass constructorthis is unavailable until super runs.
  • Using __proto__ to mutate the chain at runtime — slow, weird. Use Object.create at construction.
  • Trying to use for...in to enumerate own properties — it walks the prototype chain. Use Object.keys or hasOwnProperty.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…