两个对象都传递参数时使用对象继承

时间:2016-04-29 13:11:59

标签: javascript oop object inheritance

我有一个装备父类,它接收args和两个孩子武器和护甲也采取args。我不确定是否有一种特殊的方法来定位原型,或者我的代码实际上是不起作用但是这里是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();

2 个答案:

答案 0 :(得分:1)

首先,你的问题的答案: 你的代码并没有真正的错误,你的武器仍然有它的hp,除了它包含在对象原型中,因此在字符串化时不会显示。 有很多方法可以解决这个问题,比如我已经显示here,但根据我的说法,这不是正确的做法。

通常,原型应该只存储方法而不是实例变量,因为如果你以后决定修改原型,实例变量也会被修改,以防它通过引用传递。

更好的模式是使用Object.assign - 它是最容易理解和感觉最自然的。此外,如果您希望Weapon成为设备的子类,那么该逻辑应该封装在Weapon本身中。

以下是提出宣布武器等级的新方法:

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

由于hp也是随机生成的,因此该逻辑现在封装在Weapon中。这也是可扩展的,因为这种模式也适用于长继承链。

有些人可能会推荐ES6课程,这也是一种可行的方法,但在我看来,它是语法糖,它隐藏了代码的大部分内部工作。

Here是我的方法的工作演示。

答案 1 :(得分: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/>");