您最好的选择是拥有一个构造函数,就像您在第一个示例中所做的那样。但是,我会改变一些事情。首先,对于构造函数,您只是传入了很多数字。这很糟糕,因为很容易忘记数字的顺序。更好的方法是将一个对象传递给您的构造函数,这样您就可以标记每个属性:
function Item(props) {
this.hp = props.hp;
this.mp = props.mp;
this.dmg = props.dmg;
this.spd = props.spd;
this.luk = props.luk;
}
var BigSword = new Item({
hp: 0,
mp: 0, 5
dmg: 0,
spd: 20,
luk: 10
});
这很好,但仍然很痛苦,因为您有各种不同的项目,而且正如您所说,您必须为每个项目定义 30 个属性,这既麻烦又耗时。在这一点上,你进入了更复杂的面向对象的领域。从这里你基本上有两个选择:继承和构造。
遗产
使用对象继承来正确定义对象可能是两者中最常见的一种,而且相当简单。本质上,您有一个对象的“类”,然后是每个类的子类。因此,您可能将魔法物品和非魔法物品分为两类。如果你有一条魔法腰带,也许你想让它继承 Magical Item 类的属性。另一方面,如果你有一把基本的未附魔剑,你会想让它继承自 Non-Magical Item 类。
但是假设你有魔法卷轴和魔法药水。都是魔法道具吧?因此,您需要创建一个名为 Potions 的类和一个名为 Scrolls 的类,它们都继承自 Magical Item 类。然后你可能有某些类型的药水。治疗药水,也许——“治疗盟友魔法药水”和“治疗自我魔法药水”。所以你需要为那些不同的类——等等。
Javascript 中的继承可以通过多种不同的方式完成,并且可以非常深入,所以我不会在我的帖子中讨论它。但是,如果您想走这条路,这里有一些有用的链接可以帮助您开始继承:
作品
组合是一个大量借鉴其他松散类型语言的概念,例如 Python,它非常广泛地使用它。组合背后的基本思想是您有一个基对象类,并且每当您需要某种特定类型的对象时,您就可以向该基类添加行为或成员。这不像继承那么广为人知,但它绝对是我更喜欢的一种。
在 Javascript 中,它的工作原理是拥有一个基本构造函数 Item,然后拥有其他构造函数,这些构造函数将必要的行为添加到您的 Item。让我们看一下我用于合成的示例——创建治疗盟友的魔法药水。你在这里有几个不同的属性:魔法物品、药水、治疗。有了继承,你会做类似Item -> Magical -> Potion -> Healing Potions -> Allies
. 但是,通过组合,您可以将多个行为添加到基 Item 类,而无需设置巨大的原型链:Affect Allies
、Potion
、Healing
。
由于组合比继承简单一点(而且,我承认,我有偏见)我将在伪代码中设置一个快速示例:
// base item class
function Item(props) {
this.someProperty = props.someProperty;
this.someOtherProperty = props.someOtherProperty;
}
// potion behavior
function Potion(props) {
this.amount = props.amount; // IDK what amount means, just some random potion property
this.color = "green";
}
// healing behavior
function Healing(props) {
this.amountToHeal = props.amountToHeal;
this.cooldown = props.cooldown;
}
// behavior to affect allies
function AffectAllies(props) {
this.allies = props.allies;
for(ally in this.allies) {
this.allies[ally].affect(props.affact);
}
}
// at this point we have the various behaviors set up and we can create the Magical Potion of Heal Allies constructor:
function MassHealingPotion(props) {
var self = this;
this.amount = props.amount;
this.potion = new Potion(props);
this.effect = new Healing(props);
this.AffectAllies = new AffectAllies({
affect: function(ally) {
self.potion.affect;
},
allies: player.allies;
});
}
// you can now create a mass healing potion:
var potion = new MassHealingPotion({
weight: 50,
someProp: "someValue",
someOtherProp: "someOtherValue"
// and so on and so forth with whatever properties you want the potion to have
});
好吧,结果比我预期的要长一点,并且可能包含比我想要的更多的错误,但我希望这传达了构图的基本思想。
现在,更简单的对象创建甚至不是组合的最佳部分,因为您可以重用不同的行为。考虑一下你有一把神奇的剑,每当你发动攻击时,它就会治愈你的盟友。您所要做的就是给它 Healing 成员和 AffectAllies 成员和繁荣——治愈伙伴的魔法剑。有了继承,你必须在 Magical Items 类中创建一个 Swords 类(然后你会有两个不同的 Swords 类——一个用于非魔法剑,另一个用于魔法剑!Ew!),然后用 Healing 扩展它剑,等等等等。
您可以采用任何一种方式,继承或对象组合。两者对于您想要实现的目标同样有效。
但是性能呢?
200 件物品,每件有 30 个属性?不是问题。将它们全部粘在一个巨大的阵列/物体中,煮沸,捣碎,将它们粘在炖菜中。浏览器不在乎。不过,您最好的选择可能是一个对象:
var itemList = {
bigSword: new BigSword(...);
smallSword: new SmallSword(...);
}