35

I'm browsing the discussion for a similar topic, but can't find my situation...

Am trying call parent constructors with parameters... can't seem to get it right.

I have a PhysicsBody superclass that takes aNode as its only constructor argument:

function PhysicsBody(aNode) {
    this.userData = aNode;
    // ...
}

Of this PhysicsBody inherits a DynamicBody class. Is constructor also takes aNode as only argument... Like I would do it in Java, I'd love to call something equivalent to "super(aNode"); Can't seem to find out how.

Here's the DynamicBody class:

// Wanted to give "new PhysicsBody(this, aNode)", but that fails!
DynamicBody.prototype = new PhysicsBody();
DynamicBody.prototype.constructor=DynamicBody;

function DynamicBody(aNode) {

    // calling the parent constructor fails too:
    // PhysicsBody.prototype.constructor.call(this, aNode);
    //...
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Jem
  • 6,226
  • 14
  • 56
  • 74

2 Answers2

57

One way to do it:

function PhysicsBody( aNode ) {
    this.userData = aNode;
}

PhysicsBody.prototype.pbMethod = function () {};

function DynamicBody( aNode ) {
    PhysicsBody.call( this, aNode );
}

// setting up the inheritance
DynamicBody.prototype = Object.create( PhysicsBody.prototype );

DynamicBody.prototype.dbMethod = function () {};

Now, when you do

var pb = new PhysicsBody( '...' );

the instance pb gets a userData property and also inherits the methods from PhysicsBody.prototype (pbMethod in this case).


When you do

var db = new DynamicBody( '...' );

the instance db gets a userData property and also inherits the methods from DynamicBody.prototype (dbMethod in this case), which in turn inherits from PhysicsBody.prototype.

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Brilliant! This has illuded me since ancient time, yet it was so simple.. *faceslap* – Lars-Erik May 27 '13 at 13:25
  • @Lars-Erik To be honest, it's a mess :-). The upcoming edition of JavaScript (ECMAScript 6) will bring class syntax, which will make this pattern much simpler. – Šime Vidas May 27 '13 at 16:30
  • Then we're just left with the 10 year waiting period before all browsers with pre v6 are dead. :) I still like this way of "deriving classes" better than the various extend functions etc. (for now at least) – Lars-Erik Jun 21 '13 at 12:51
  • @Lars-Erik Feel free to start using ES6 classes **today** with a ES6-to-Es5 transpliler. You can transpile in-browser, or before with e.g. a Grunt task https://npmjs.org/package/grunt-traceur – Šime Vidas Jun 21 '13 at 13:40
  • Thanks for the tip. Will have a look. :) – Lars-Erik Jun 21 '13 at 15:07
  • still I don't understand how come it works - why is the DynamicBody an instanceof PhysicsBody? they both inherit from object but they do not inherit from each other! (assuming that PhysicsBody.prototype points to a generic Object...) – Novellizator Apr 10 '14 at 14:31
  • Why do we need to do `DynamicBody.prototype = Object.create( PhysicsBody.prototype );` instead of just `DynamicBody.prototype = PhysicsBody.prototype;` ? - EDIT: Ah, its so we don't clobber the parent prototype when adding methods to `DynamicBody`'s prototype. – mclaassen May 10 '15 at 21:37
10

If I understand you correctly, by saying you want to inherit the parent constructor arguments, you mean that new DynamicBody(1, 2, 3) will internally call PhysicsBody(1, 2, 3) for the DynamicBody instance.

This can be accomplished by using .apply and passing arguments along: http://jsfiddle.net/pmkrQ/.

function DynamicBody() {
    PhysicsBody.apply(this, arguments);
}
pimvdb
  • 151,816
  • 78
  • 307
  • 352