How to inherit from a class 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

Tags:

Javascript

Oop