2016-08-11 9 views
0

私はJavaScriptでOOPを学ぶしようとしていますし、私の主なインスピレーションはこれまでのところ、次のサイトとなっている:私は直面していますhttp://phrogz.net/js/classes/OOPinJS2.html祖先コンストラクタをJavaScriptで順番に呼び出す方法は?

問題は、私は再び持っている親クラスを持つクラスを、持っているということです親クラスであり、コンストラクタのチェーンを介してトップレベルの親まで引数を渡す巧妙な方法を見つけることはできません。

私は1つ上のレベルを渡すことができますが、私のコードは無限の再帰的ループに入ります。

// Define inheritance function: 

Function.prototype.inheritsFrom = function(parentClassOrObject){ 
    this.prototype = new parentClassOrObject; 
    this.prototype.constructor = this; 
    this.prototype.parent = parentClassOrObject.prototype; 
} 

// Define objects (classes) and inheritance structure: 

function Human(name){ 
    this.name   = name; 
} 

function Criminal(name,crime){ 
    this.parent.constructor.call(this, name); 
    this.crime  = crime; 
} 
Criminal.inheritsFrom(Human); 

function Prisoner(name,crime,centence){ 
    this.parent.constructor.call(this, name, crime); 
    this.centence  = centence; 
} 
Prisoner.inheritsFrom(Criminal); 

// Create instances: 

h = new Human('Anne')    // > Human {name: "Anne"}  
c = new Criminal('Jack','theft') // > Criminal {name: "Jack", crime: "theft"}  
p = new Prisoner('Jon','murder',21) // > Error 

// > Error description: Uncaught RangeError: Maximum call stack size exceeded(…) 

明らかに囚人が正常に親コンストラクタを呼び出し、すなわち、刑事コンストラクタ:

次のコードは、問題をスケッチ。しかし、犯罪コンストラクタが親コンストラクタを呼び出すと、 "this"は依然として同じPrisonerオブジェクトを参照しているので、親コンストラクタが(意図されたHumanコンストラクタの代わりに)Criminalコンストラクタに再度呼び出されるため、無限再帰ループが形成されている場合。

問題を解決するには簡単な方法(できればセクシー)がありますか?または継承を実装するためのより良い方法は?

+0

継承モデルが間違っています。 http://blog.slaks.net/2013-09-03/traditional-inheritance-in-javascript/ – SLaks

+0

を読んでください。プロトタイプに 'parent'を置くことはできません。すべてのレベルにプロトタイプが1つしかないからです。 – SLaks

+0

@SLaksブログから最終的な '継承'関数を試してみたとき、私はエラーを受け取りました。 –

答えて

0

@SLaksの投稿とSebastian Portoの優れたplain-English guide to Javascript prototypesに基づいて、私は下にスケッチした解決策を設定しました。

この解決策がない場合は、私にお知らせください。 :)

理想的には、継承がコンストラクタ内から設定できるといいと思うが、それは実現可能ではないようだ...だから、この解決策は得られるほど良いと思われる。 :)

inherits = function(child, parent) { 
    child.parent  = parent; 
    child.prototype = Object.create(parent.prototype, { 
    constructor: { 
     value: child, 
     enumerable: false, 
     writable: true, 
     configurable: true 
    } 
    }); 
    console.log('Inheritance set: ' + child.name + '.parent = ' + parent.name); 
}; 

function Human(name){ 
    this.name   = name; 
} 

function Criminal(name,crime){ 
    Human.call(this, name); 
    this.crime  = crime; 
}inherits(Criminal,Human); 

function Prisoner(name,crime,centence){ 
    Criminal.call(this, name, crime); 
    this.centence  = centence; 
}inherits(Prisoner,Criminal); 

h = new Human('Anne')     // > Human {name: "Anne"} 
c = new Criminal('Jack','theft')  // > Criminal {name: "Jack", crime: "theft"} 
p1 = new Prisoner('John','murder',21); // > Prisoner successfully created! 
p2 = new Prisoner('Peter','robbery',7); // > Prisoner successfully created!