Skip to main content
JavaScript uses prototypal inheritance — objects inherit directly from other objects via the prototype chain. The class syntax (ES6) is syntactic sugar over this prototype-based system.

Prototype chain

Every object has an internal [[Prototype]] link (accessible via Object.getPrototypeOf() or __proto__). Property lookups walk the chain until found or null is reached.
const animal = {
  breathe() { return "breathing"; }
};

const dog = Object.create(animal);
dog.bark = function() { return "woof"; };

console.log(dog.bark());    // "woof" — own property
console.log(dog.breathe()); // "breathing" — from prototype
console.log(Object.getPrototypeOf(dog) === animal); // true

Constructor functions

function Person(name, age) {
  this.name = name;
  this.age = age;
}

// Methods go on the prototype, not the instance
Person.prototype.greet = function() {
  return `Hi, I'm ${this.name}`;
};

const alice = new Person("Alice", 30);
alice.greet(); // "Hi, I'm Alice"
When called with new, a constructor: (1) creates a new object, (2) sets its [[Prototype]] to Constructor.prototype, (3) binds this to the new object, (4) returns the object automatically.

Class syntax (ES6)

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    return `${this.name} makes a noise.`;
  }
}

class Dog extends Animal {
  speak() {
    return `${this.name} barks.`;
  }
}

const d = new Dog("Rex");
d.speak(); // "Rex barks."
d instanceof Dog;    // true
d instanceof Animal; // true

Key concepts

ConceptDescription
prototypeProperty on constructor functions; becomes [[Prototype]] of instances
__proto__Accessor to [[Prototype]] of an instance (use Object.getPrototypeOf instead)
Object.create(proto)Creates a new object with proto as its prototype
hasOwnProperty(key)Returns true if the property is on the object itself, not the prototype
instanceofChecks if Constructor.prototype exists in the prototype chain

Prototype vs own property

function Car(model) {
  this.model = model; // own property
}
Car.prototype.wheels = 4; // shared via prototype

const tesla = new Car("Model 3");
tesla.hasOwnProperty("model");  // true
tesla.hasOwnProperty("wheels"); // false
tesla.wheels; // 4 (from prototype)

Common interview questions

  • prototype is a property on constructor functions (and classes). It is the object that becomes the [[Prototype]] of instances created with new.
  • __proto__ (or Object.getPrototypeOf(obj)) is a property on every object that points to its prototype — the object it inherits from.
function Foo() {}
const f = new Foo();

f.__proto__ === Foo.prototype; // true
Foo.prototype.constructor === Foo; // true
Object.create(proto) creates a new object with proto as its prototype, without calling any constructor function. new Constructor() calls the constructor and also sets up the prototype link automatically.
const base = { greet() { return "hello"; } };

// Object.create — no constructor call
const obj = Object.create(base);

// Equivalent manual version of what new does
function manualNew(Constructor, ...args) {
  const obj = Object.create(Constructor.prototype);
  Constructor.apply(obj, args);
  return obj;
}
Classical inheritance (Java, C++) — classes are blueprints; instances are copies of the class. Inheritance happens through class hierarchies at compile time.Prototypal inheritance (JavaScript) — objects inherit directly from other objects. There are no classes at the language level (ES6 class is syntax sugar). Inheritance is dynamic — you can modify prototypes at runtime.