Полиморфизм и глубокое наследование в JS - PullRequest
2 голосов
/ 27 июля 2011

Я использую шаблон наследования прототипа JS от Гэвина Кистнера , и я не совсем уверен, почему глубокое наследование не работает для меня.

Я хочу, чтобы C наследовал от B, наследовал от 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.

Когда я звоню foo.init(), я на самом деле звоню C.init()
Внутри C.init() 'this' имеет тип C
-> this.parent.init.call( this, arg ) фактически звонит B.init()
Внутри B.init() «this» по-прежнему относится к типу C (из-за .call(this))
-> this.parent.init.call( this, arg ) снова звонит B.init()

И поэтому он входит в бесконечный цикл вызова на B.init() ...

Что я делаю не так?
Должен ли я просто переименовать 'init' во что-то еще для B и C? Я бы предпочел не делать этого, потому что текущий способ позволяет мне вызывать obj.init(), имеет ли obj тип A, B или C ...

Ответы [ 2 ]

1 голос
/ 27 июля 2011

Изменить B.parent.init.call( this, arg ); на B.prototype.parent.init.call( this, arg );.

0 голосов
/ 27 июля 2011

Это не отвечает на ваш вопрос, но я недавно немного поработал с наследованием JavaScript.Если вы хотите пойти по классическому маршруту, я действительно рекомендую JS.Class ;это библиотека, которая делает классы действительно простыми.

Если вы можете, вам следует избегать использования библиотеки, но если вы не хотите иметь дело с головной болью наследования / прототипирования JavaScript, я могу порекомендовать JS.Class.

...