How to inherit from a class in javascript?

In PHP/Java one can do:

class Sub extends Base
{
}

And automatically all public/protected methods, properties, fields, etc of the Super class become a part of the Sub class which can be overridden if necessary.

What's the equivalent for that in Javascript?


In JavaScript you don't have classes but you can get inheritance and behavior reuse in many ways:

Pseudo-classical inheritance (through prototyping):

function Super () {
  this.member1 = 'superMember1';
}
Super.prototype.member2 = 'superMember2';

function Sub() {
  this.member3 = 'subMember3';
  //...
}
Sub.prototype = new Super();

Should be used with the new operator:

var subInstance = new Sub();

Function application or "constructor chaining":

function Super () {
  this.member1 = 'superMember1';
  this.member2 = 'superMember2';
}


function Sub() {
  Super.apply(this, arguments);
  this.member3 = 'subMember3';
}

This approach should also be used with the new operator:

var subInstance = new Sub();

The difference with the first example is that when we apply the Super constructor to the this object inside Sub, it adds the properties assigned to this on Super, directly on the new instance, e.g. subInstance contains the properties member1 and member2 directly (subInstance.hasOwnProperty('member1') == true;).

In the first example, those properties are reached through the prototype chain, they exist on an internal [[Prototype]] object.

Parasitic inheritance or Power Constructors:

function createSuper() {
  var obj = {
    member1: 'superMember1',
    member2: 'superMember2'
  };

  return obj;
}

function createSub() {
  var obj = createSuper();
  obj.member3 = 'subMember3';
  return obj;
}

This approach is based basically on "object augmenting", you don't need to use the new operator, and as you can see, the this keyword is not involved.

var subInstance = createSub();

ECMAScript 5th Ed. Object.create method:

// Check if native implementation available
if (typeof Object.create !== 'function') {
  Object.create = function (o) {
    function F() {}  // empty constructor
    F.prototype = o; // set base object as prototype
    return new F();  // return empty object with right [[Prototype]]
  };
}

var superInstance = {
  member1: 'superMember1',
  member2: 'superMember2'
};

var subInstance = Object.create(superInstance);
subInstance.member3 = 'subMember3';

The above method is a prototypal inheritance technique proposed by Crockford.

Object instances inherit from other object instances, that's it.

This technique can be better than simple "object augmentation" because the inherited properties aren't copied over all the new object instances, since the base object is set as the [[Prototype]] of the extended object, in the above example subInstance contains physically only the member3 property.


I have changed how I do this now, I try to avoid using constructor functions and their prototype property, but my old answer from 2010 is still at the bottom. I now prefer Object.create(). Object.create is available in all modern browsers.

I should note that Object.create is usually much slower than using new with a function constructor.

//The prototype is just an object when you use `Object.create()`
var Base = {};

//This is how you create an instance:
var baseInstance = Object.create(Base);

//If you want to inherit from "Base":
var subInstance = Object.create(Object.create(Base));

//Detect if subInstance is an instance of Base:
console.log(Base.isPrototypeOf(subInstance)); //True

jsfiddle

One of the big benefits of using Object.create is being able to pass in a defineProperties argument, which gives you significant control over how properties on the class can be accessed and enumerated over, and I also use functions to create instances, these serve as constructors in a way, as you can do initialization at the end instead of just returning the instance.

var Base = {};

function createBase() {
  return Object.create(Base, {
    doSomething: {
       value: function () {
         console.log("Doing something");
       },
    },
  });
}

var Sub = createBase();

function createSub() {
  return Object.create(Sub, {
    doSomethingElse: {
      value: function () {
        console.log("Doing something else");
      },
    },
  }); 
}

var subInstance = createSub();
subInstance.doSomething(); //Logs "Doing something"
subInstance.doSomethingElse(); //Logs "Doing something else"
console.log(Base.isPrototypeOf(subInstance)); //Logs "true"
console.log(Sub.isPrototypeOf(subInstance)); //Logs "true

jsfiddle

This is my original answer from 2010:

function Base ( ) {
  this.color = "blue";
}

function Sub ( ) {

}
Sub.prototype = new Base( );
Sub.prototype.showColor = function ( ) {
 console.log( this.color );
}

var instance = new Sub ( );
instance.showColor( ); //"blue"

For those who reach this page in 2019 or after

With the latest version of the ECMAScript standard (ES6), you can use the keyword class.

Note that the class definition is not a regular object; hence there are no commas between class members. To create an instance of a class, you must use the new keyword. To inherit from a base class, use extends:

class Vehicle {
   constructor(name) {
      this.name = name;
      this.kind = 'vehicle';
   }
   getName() {
      return this.name;
   }   
}

// Create an instance
var myVehicle = new Vehicle('rocky');
myVehicle.getName(); // => 'rocky'

To inherit from a base class, use extends:

class Car extends Vehicle {
   constructor(name) {
      super(name);
      this.kind = 'car'
   }
}

var myCar = new Car('bumpy');

myCar.getName(); // => 'bumpy'
myCar instanceof Car; // => true
myCar instanceof Vehicle; // => true

From the derived class, you can use super from any constructor or method to access its base class:

  • To call the parent constructor, use super().
  • To call another member, use, for example, super.getName().

There’s more to using classes. If you want to dig deeper into the subject, I recommend “Classes in ECMAScript 6” by Dr. Axel Rauschmayer.*

source


Well, in JavaScript there is no "class inheritance", there is just "prototype inheritance". So you don't make a class "truck" and then mark it as a subclass of "automobile". Instead, you make an object "Jack" and say that it uses "John" as a prototype. If John knows, how much "4+4" is, then Jack knows it, too.

I suggest you read Douglas Crockford's article about prototypal inheritance here: http://javascript.crockford.com/prototypal.html He also shows how you can make JavaScript have "look-alike" inheritance as in other OO languages and then explains that this actually means breaking javaScript in a way it was not meant to be used.


I find this quote to be the most enlightening:

In essence, a JavaScript "class" is just a Function object that serves as a constructor plus an attached prototype object. (Source: Guru Katz)

I like using constructors rather than objects, so I'm partial to the "pseudo-classical inheritance" method described here by CMS. Here is an example of multiple inheritance with a prototype chain:

// Lifeform "Class" (Constructor function, No prototype)
function Lifeform () {
    this.isLifeform = true;
}

// Animal "Class" (Constructor function + prototype for inheritance)
function Animal () {
    this.isAnimal = true;
}
Animal.prototype = new Lifeform();

// Mammal "Class" (Constructor function + prototype for inheritance)
function Mammal () {
    this.isMammal = true;
}
Mammal.prototype = new Animal();

// Cat "Class" (Constructor function + prototype for inheritance)
function Cat (species) {
    this.isCat = true;
    this.species = species
}
Cat.prototype = new Mammal();

// Make an instance object of the Cat "Class"
var tiger = new Cat("tiger");

console.log(tiger);
// The console outputs a Cat object with all the properties from all "classes"

console.log(tiger.isCat, tiger.isMammal, tiger.isAnimal, tiger.isLifeform);
// Outputs: true true true true

// You can see that all of these "is" properties are available in this object
// We can check to see which properties are really part of the instance object
console.log( "tiger hasOwnProperty: "
    ,tiger.hasOwnProperty("isLifeform") // false
    ,tiger.hasOwnProperty("isAnimal")   // false
    ,tiger.hasOwnProperty("isMammal")   // false
    ,tiger.hasOwnProperty("isCat")      // true
);

// New properties can be added to the prototypes of any
// of the "classes" above and they will be usable by the instance
Lifeform.prototype.A    = 1;
Animal.prototype.B      = 2;
Mammal.prototype.C      = 3;
Cat.prototype.D         = 4;

console.log(tiger.A, tiger.B, tiger.C, tiger.D);
// Console outputs: 1 2 3 4

// Look at the instance object again
console.log(tiger);
// You'll see it now has the "D" property
// The others are accessible but not visible (console issue?)
// In the Chrome console you should be able to drill down the __proto__ chain
// You can also look down the proto chain with Object.getPrototypeOf
// (Equivalent to tiger.__proto__)
console.log( Object.getPrototypeOf(tiger) );  // Mammal 
console.log( Object.getPrototypeOf(Object.getPrototypeOf(tiger)) ); // Animal
// Etc. to get to Lifeform

Here is another good resource from MDN, and here is a jsfiddle so you can try it out.