JavaScript Prototypes

Understand prototype chains, inheritance, and how property lookup works

Overview

Every JavaScript object has an internal link to another object called its prototype, forming a chain that ends at null. When you read a property, the engine walks this chain until it finds a match or gives up. Classes are largely syntactic sugar over this prototype mechanism.

Syntax / Usage

Use Object.create to set a prototype directly, Object.getPrototypeOf to inspect it, and constructor functions or class to share methods via prototype.

const animal = {
  describe() {
    return `${this.name} makes a sound`
  },
}

const dog = Object.create(animal) // dog's prototype is animal
dog.name = 'Rex'
console.log(dog.describe()) // 'Rex makes a sound'

console.log(Object.getPrototypeOf(dog) === animal) // true
console.log(dog.hasOwnProperty('name')) // true
console.log(dog.hasOwnProperty('describe')) // false (inherited)

Examples

Constructor functions attach shared methods to prototype, so instances reuse one copy:

function Point(x, y) {
  this.x = x
  this.y = y
}

Point.prototype.distanceTo = function (other) {
  return Math.hypot(this.x - other.x, this.y - other.y)
}

const a = new Point(0, 0)
const b = new Point(3, 4)
console.log(a.distanceTo(b)) // 5

class syntax produces the same prototype chain under the hood:

class Shape {
  constructor(name) {
    this.name = name
  }
  describe() {
    return `a ${this.name}`
  }
}

class Circle extends Shape {
  constructor(r) {
    super('circle')
    this.r = r
  }
  area() {
    return Math.PI * this.r ** 2
  }
}

const c = new Circle(2)
console.log(c.describe(), c.area().toFixed(2)) // 'a circle' '12.57'
console.log(Object.getPrototypeOf(Circle.prototype) === Shape.prototype) // true

Common Mistakes

  • Mutating a shared prototype at runtime, affecting every instance unexpectedly
  • Using __proto__ in performance-sensitive code instead of Object.getPrototypeOf
  • Forgetting new, so this binds to the global object or is undefined
  • Storing mutable state (like arrays) on the prototype, accidentally sharing it across instances
  • Confusing instanceof (checks the chain) with hasOwnProperty (checks own keys)

See Also

objects functions javascript-proxies-reflect