2

I'm using the JS prototype inheritance pattern from Gavin Kistner and I'm not quite sure why deep inheritance doesn't work for me.

I want C inherits from B inherits from A...

Function.prototype.inheritsFrom = function( parentClassOrObject )
{
   if ( parentClassOrObject.constructor == Function )
   {
      //Normal Inheritance
      this.prototype = new parentClassOrObject;
      this.prototype.constructor = this;
      this.prototype.parent = parentClassOrObject.prototype;
   }
   else
   {
      //Pure Virtual Inheritance
      this.prototype = parentClassOrObject;
      this.prototype.constructor = this;
      this.prototype.parent = parentClassOrObject;
   }
   return this;
}

function A() {
   // ...
}
A.prototype.init = function( arg ) {
   // ...
}

function B() {
   A.apply( this, arguments );  // call super constructor
   // ...
}
B.inheritsFrom( A );
B.prototype.init = function( arg ) {
    B.parent.init.call( this, arg );
    // ...
}

function C() {
   B.apply( this, arguments ); // call super constructor
   // ...
}
C.inheritsFrom( B );
C.prototype.init = function( arg ) {
   this.parent.init.call( this, arg );
   // ...
}

var foo = new C();
foo.init( 10 );  

// Throws an exception: infinite call loop.

When I call foo.init(), I'm actually calling C.init()
Inside C.init() 'this' is of type C
-> this.parent.init.call( this, arg ) is actually calling B.init()
Inside B.init() 'this' is still of type C ( because of .call(this))
-> this.parent.init.call( this, arg ) is, again, calling B.init()

And therefore it goes into an infinite call loop on B.init() ...

What am I doing wrong ?
Should I simply rename 'init' to something else for B and C ? I would rather not, because the current way allows me to call obj.init() whether obj is of type A, B or C...

4
  • 2
    inheritance like this is just wrong. Classical OO like this should not be hacked into JavaScript. Please use prototypical OO and traits instead Commented Jul 27, 2011 at 19:25
  • @Raynos Raynos is right. Raynos, can you add-in a link to an example you like? Commented Jul 27, 2011 at 20:46
  • 1
    TraitsJS is a great library for prototypical OO. Just limiting yourself to only use Object.create, Trait and only have prototypical inheritance chains one level deep should produce good prototypical OO Commented Jul 27, 2011 at 21:02
  • This has been stale for a while, but in the meantime I've learned a bit more and got to agree with Raynos, thanks for the heads up! Commented Aug 21, 2013 at 17:57

2 Answers 2

1

Change B.parent.init.call( this, arg ); to B.prototype.parent.init.call( this, arg );.

Sign up to request clarification or add additional context in comments.

1 Comment

Aaaaah see, this was my problem. It was a typo, this line was actually "this.prototype.parent.init.call( this, arg )". I changed it to use the class name instead of "this", and added '.prototype' as you suggested and it works perfectly ! Thanks !!
0

This doesn't answer your question, but I have been doing some work with JavaScript inheritance recently. If you want to go the classical route, I can really recommend JS.Class; it's a library that makes classes really easy.

If you can, you should avoid using the library, but if you don't want to deal with the headache of JavaScript inheritance/prototyping, I can recommend JS.Class.

1 Comment

You should indeed avoid all classical OO emulation. I would also recommend traitsJS as prototypical OO alternative

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.