2016-04-29 4 views
0

私はargsを取るEquipment親クラスとargsを取る2つの子WeaponとArmorを持っています。私は試作品を対象とする特別な方法があるかどうかわからないか、私のコードは、実際にここで働いたがされていない場合、私はの値に基づいて、各オブジェクト内の引数に使用する変数を作成する必要がshortened DEMO両方のオブジェクトが引数を渡すときにオブジェクト継承を使用する

です他の変数、乱数を使用するアルゴリズムなどがあります。それぞれのアイテムはユニークなので、私は武器の被害と同時に装備用のHPを作る必要があり、どうやってそれを行うのか分かりません。

function Equipment(hp) { 
    var self = this; 
    this.hp = hp; 
} 
//create subclass for weapons 
function Weapon(baseDam) { 
    var self = this; 
    this.baseDam = baseDam; 
} 

function generateEquipment() { 
    hp = Math.round(Math.random() * 10); 
    baseDam = Math.round(Math.random() * 50); 
    Weapon.prototype = new Equipment(hp); 
    weapon = new Weapon(baseDam); 
    stringed = JSON.stringify(weapon); 
    alert(stringed); 
} 

generateEquipment(); 
+0

、あなたが実際に達成したいかについて、もう少し言うてくださいだろうか? – lipp

+0

私は自分の質問を編集しました。明確になることを願って – Shniper

+0

近づいています。なぜメソッドが "generateEquipment"と呼ばれるのか、なぜ "武器"を返すのか分かりません。あなたはこの機能に他の「装備」を作るつもりですか? – lipp

答えて

1

まず、あなたの質問への答え: あなたのコードは本当に間違っていない、とあなたの武器は、まだそのオブジェクトのプロトタイプに含まれていることを除いて、その馬力を持っているので、文字列化する場合は表示されません。 hereと表示されているように、これを回避する方法がありますが、これは正しい方法ではありません。

通常、プロトタイプは、後でプロトタイプを変更すると、インスタンス変数が参照渡しの場合に変更されるため、インスタンス変数ではなくメソッドのみを格納する必要があります。

より良いパターンは、Object.assignを使用することです。最も理解しやすく、最も自然な感じです。さらに、Weaponが機器のサブクラスであることを期待するならば、そのロジックはWeaponにカプセル化されるべきです。 HPはまた、ランダムに生成されているので

function Weapon(baseDam) { 
    var self = this; 
    var hp = Math.round(Math.random() * 10); 
    Object.assign(self, Equipment.prototype, new Equipment(hp)); 
    this.baseDam = baseDam; 
} 

、そのロジックは今武器にカプセル化されています。ここでは

はあなたの武器クラスを宣言する提案された新しい方法です。このパターンは長い継承チェーンでも機能するので、これもスケーラブルです。

ES6クラスもお勧めしますが、これは動作するアプローチですが、私の意見では、コードの内部動作のほとんどを隠す構文糖です。

Hereは私のアプローチによるデモです。

+0

これは確かに実用的な答えです、私の唯一の問題は、私の実際のコードでは、10個以上の変数が装備にあり、関数でそのコードを繰り返す必要がないことです。すべてがlocalStorageを通過する必要があり、私はlocalStorageに関数を渡すことができません – Shniper

+0

あなたはすべての共通変数を取って親クラスに入れておかなければならないでしょう...すべての武器固有と防具固有の変数は、コンストラクタ[こちらを参照](https://jsfiddle.net/v5kdygy5/) localStorageについては、コンストラクタではなくインスタンスを保存したいと思っていますので、 'localStorage.weapon1 = new Weapon(12);'はうまく動作します。 –

+0

これを正しく理解しているのであれば、generateEquipment関数の代わりにWeaponとArmorに変数を作成するだけです。 – Shniper

0

あなたが描いている「パターン」は「合成」と呼ばれ、非常に強力です。新しいクラスやオブジェクトを結合/合成するには、さまざまな方法があります。

あなたの質問とコメントを読んで、あまりにも多くの(繰り返された)コードなしで多くの異なるタイプの機器を定義することに主に関心があるようです。

generateEquipmentメソッドにクラス名の配列を渡し、新しいカスタムコンストラクタを返すことについて考えましたか?ここでは例です:

function Equipment(hp) { 
 
    this.hp = Math.round(hp); 
 
} 
 

 
Equipment.prototype.describe = function() { 
 
    return "This piece of equipment has " + this.hp + " hitpoints"; 
 
} 
 

 
function Weapon(baseDam) { 
 
    this.baseDam = Math.round(baseDam); 
 
} 
 

 
Weapon.prototype.describe = function() { 
 
    return "The weapon does " + this.baseDam + " damage"; 
 
} 
 

 
function generateCustomEquipment(types) { 
 
    var CustomEquipment = function() { 
 
    var self = this; 
 

 
    // Create the properties for all types 
 
    types.forEach(function(type) { 
 
     type.call(self, Math.random() * 100); 
 
    }); 
 
    }; 
 

 
    CustomEquipment.prototype.describe = function() { 
 
    var self = this; 
 

 
    // Combine the 'describe' methods of all composed types 
 
    return types 
 
     .map(function(type) { 
 
     return type.prototype.describe.call(self); 
 
     }) 
 
     .join(". "); 
 
    } 
 

 
    return CustomEquipment; 
 
} 
 

 
var Sword = generateCustomEquipment([Equipment, Weapon]); 
 
var Armor = generateCustomEquipment([Equipment]); 
 
var Arrow = generateCustomEquipment([Weapon]); 
 

 
var sword1 = new Sword(); 
 
document.writeln("A sword: " + sword1.describe() + "<br/>"); 
 

 
var armor1 = new Armor(); 
 
document.writeln("A piece of armor: " + armor1.describe() + "<br/>"); 
 

 
var arrow1 = new Arrow(); 
 
document.writeln("An arrow: " + arrow1.describe() + "<br/>");

関連する問題