2

私はJS prototype inheritance pattern from Gavin Kistnerを使用しています。深い継承がなぜ機能しないのかよく分かりません。 >this.parent.init.call(this, arg) - 私はfoo.init()を呼び出すと、私はCがBから継承したいJSの多相性と深い継承

が... 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. 

を継承し、私は実際には 'これは' タイプCの
あるC.init()インサイドC.init()
を呼んでいますagai、>this.parent.init.call(this, arg)ある - 実際にB.init()
インサイドB.init()を呼んでいる 'これは'
が(理由.call(this)の)タイプCのままですnは、私が間違って何をやっている...

B.init()

を呼び出し、したがって、それはB.init()上無限のコールループに入りますか?
私は単に 'init'の名前をBとCの名前に変えるべきですか?現在の方法では、objがタイプA、B、Cのいずれであるかは、obj.init()と呼ぶことができるので、私はむしろそうしないでしょう。

+2

このような継承は間違っています。このような古典的なオブジェクト指向は、JavaScriptにハックするべきではありません。代わりにプロトタイプのOOと特性を使用してください – Raynos

+0

@レイノスレイノスが正しいです。 Raynos、好きなサンプルへのリンクを追加できますか? –

+1

[TraitsJS](http://traitsjs.org/)は、プロトタイプOO用の素晴らしい図書館です。 'Object.create'、' Trait'だけを使うように制限し、プロトタイプの継承チェーンを深いところに置いて良いプロトタイプのOO – Raynos

答えて

1

変更B.parent.init.call(this, arg);B.prototype.parent.init.call(this, arg);です。

+0

Aaaaah参照してください、これは私の問題でした。それはタイプミスで、この行は実際には "this.prototype.parent.init.call(this、arg)"でした。 "this"の代わりにクラス名を使用するように変更し、提案したように '.prototype'を追加しました。これは完全に機能します!ありがとう!! –

0

これはあなたの質問に答えることはできませんが、私は最近JavaScriptの継承に関するいくつかの作業を行っています。あなたが古典的なルートを行きたい場合は、私は本当にお勧めすることができますJS.Class;クラスを本当に簡単にするライブラリです。

可能であれば、ライブラリの使用を避けるべきですが、JavaScriptの継承/プロトタイプの頭痛に対処したくない場合は、JS.Classをおすすめします。

+0

すべての古典的なOOエミュレーションを避けるべきです。私はまた、[traitsJS](http://traitsjs.org/)をプロトタイプのOOの代替としてお勧めします – Raynos

+0

これは間違っています。それは私の質問に答えた;) –