Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you do inheritance in JavaScript without sharing the same instance of the super class between all instances of the sub class?

I noticed that every tutorial on how to do JavaScript inheritance does this:

SubClass.prototype = new SuperClass();

But this will create a single instance of the super class and share it among all the instances of the sub class.

The problem is that I would like to pass arguments to the super class constructor which originate from arguments passed to the sub class.

In Java this would be done like this:

class SubClass extends SuperClass {
  public SubClass(String s) {
    super(s);
  }
}

I tried doing something like this:

function SubClass(args) {
  this.constructor.prototype = new SuperClass(args);
}

But this will not work. So is there a way to do this in JavaScript?

like image 538
mtanti Avatar asked Jan 05 '12 00:01

mtanti


People also ask

Can you inherit from multiple classes in JavaScript?

No, in JavaScript, a class cannot extend from multiple classes, which is also known as “multiple inheritance”. In JavaScript, objects can only be associated with a single prototype, and extending multiple classes would mean that an object associates with multiple prototypes, which is not possible.

How does inheritance work in JavaScript?

When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.

How do I inherit a class in JavaScript?

By calling the super() method in the constructor method, we call the parent's constructor method and gets access to the parent's properties and methods. Inheritance is useful for code reusability: reuse properties and methods of an existing class when you create a new class.

Why multiple inheritance is not supported in JavaScript?

Problem occurs in method call, when display() method will be called with Test class object which method will be called, will it be of Class1 or Class2. This is ambiguity problem because of which multiple inheritance is not supported in java.


3 Answers

A common pattern is the following:

A temporary constructor is created, which inherits from the parent constructor's prototype. The child constructor's prototype is then set to an instance of the temporary constructor.

function inherits(Child, Parent) {
    var Tmp = function() {};
    Tmp.prototype = Parent.prototype;
    Child.prototype = new Tmp();
    Child.prototype.constructor = Child;
}

Inside the child constructor you then have to call the parent's constructor:

function Child(a, b, c) {
    Parent.call(this, a, b);
}

inherits(Child, Parent);

// add prototype properties here

Inside this function call, this will refer to the new object which gets created when you call new Child(), hence, whatever initialization is performed inside Parent, it is applied to the new object we pass.

like image 101
Felix Kling Avatar answered Nov 09 '22 05:11

Felix Kling


This is how I have always done it.

// Parent object
function Thing(options)
{ 
    //do stuff
}

Thing.prototype.someMethod = function(){
    // some stuff
   console.log('hello');
}

// child object which inherits from the parent
function OtherThing(options)
{       
    Thing.call(this, options);
    // do stuff for otherthing
}

OtherThing.prototype = new Thing();

OtherThing.prototype.someMethod = function(){
   // call things original function
   Thing.prototype.someMethod.call(this);

   // now do anything different
   console.log('other thing says hi');
}


var testObj = new OtherThing();
    testObj.someMethod();

Live Demo

like image 40
Loktar Avatar answered Nov 09 '22 04:11

Loktar


But this will create a single instance of the super class and share it among all the instances of the sub class.

Yes, that's how inheritance works in JavaScript.

So is there a way to do this in JavaScript?

Not without horribly subverting/twising/misusing the existing paradigm. I recommend taking a different approach to implementing whatever you're aiming for.

like image 38
Matt Ball Avatar answered Nov 09 '22 06:11

Matt Ball