Prototypes in JavaScript

Introduction

Every object has an internal link to another object called its prototype. When you read user.save, JavaScript looks on user, then walks the prototype chain until it finds save or returns undefined. Classes are built on this model—understanding prototypes explains instanceof, method sharing, and inheritance.

Prerequisites

[[Prototype]] and __proto__

javascript
// Objects inherit from Object.prototype by default
const obj = { a: 1 };
console.log(Object.getPrototypeOf(obj) === Object.prototype);
 
const proto = Object.getPrototypeOf(obj);
console.log(proto.toString === Object.prototype.toString);

Avoid relying on __proto__ in application code—use Object.getPrototypeOf / Object.setPrototypeOf or classes.

Methods Live on the Prototype

javascript
// Constructor function (classic)
function Animal(name) {
  this.name = name;
}
 
Animal.prototype.speak = function () {
  return `${this.name} makes a sound`;
};
 
const dog = new Animal("Rex");
console.log(dog.speak());
console.log(dog.hasOwnProperty("name"));
console.log(dog.hasOwnProperty("speak"));

speak is shared by all Animal instances—memory efficient.

Class Desugars to Prototype

javascript
// ES6 class — same idea
class Vehicle {
  constructor(type) {
    this.type = type;
  }
 
  info() {
    return `Vehicle: ${this.type}`;
  }
}
 
const car = new Vehicle("car");
console.log(Object.getPrototypeOf(car) === Vehicle.prototype);

Prototype Chain Lookup

javascript
// Inherited method from Object.prototype
const point = { x: 1, y: 2 };
console.log(point.toString());
 
// Shadowing: own property hides prototype
point.toString = () => "custom";
console.log(point.toString());

Object.create

javascript
// New object with explicit prototype
const personProto = {
  greet() {
    return `Hi, ${this.name}`;
  },
};
 
const ada = Object.create(personProto);
ada.name = "Ada";
console.log(ada.greet());

Mini Example: Shared Behavior Without Class

javascript
// Prototype object for many records
const listMethods = {
  add(item) {
    this.items.push(item);
  },
  size() {
    return this.items.length;
  },
};
 
function createList() {
  const list = Object.create(listMethods);
  list.items = [];
  return list;
}
 
const todos = createList();
todos.add("write docs");
todos.add("run build");
console.log(todos.size());

FAQ

Prototype vs class?

class is clearer syntax; prototypes are the underlying mechanism.

Can I change a prototype after creating instances?

Yes—existing instances see new methods added to their prototype; be careful in libraries.

Multiple inheritance?

JavaScript has single prototype chain; mixins copy methods onto prototypes or use composition.

What comes next?

Constructorsconstructor, new, and static members.