Your best bet is to have a constructor, as you have in your first example. However, I'd change a few things. First of all, for the constructor, you're simply passing in a lot of numbers. This is bad, because it's very easy to forget the order in which your numbers go. A better way to go would be to pass in an object to your constructor, so you can label each property:
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
});
This is nice, but still a pain, because you have all sorts of different items, and as you said, you'd have to define 30 properties for each item, which gets both messy and time-consuming. At this point you get into the realm of more complex object oriented stuff. From here you have basically two options: inheritance and construction.
Inheritance
Using object inheritance to properly define objects is one probably the more common of the two, and is fairly straightforward. In essence, you have a "class" of object, and then sub-classes of each class. So you might have Magical Items and Non-Magical Items as two classes. If you had a magic belt, perhaps, you'd want to make it inherit the properties of the Magical Item class. On the other hand, if you had a basic un-charmed sword, you'd want to make it inherit from the Non-Magical Item class.
But say you have magical scrolls and magical potions. Those are both magical items, right? So you'd want to make a class called Potions and a class called Scrolls, which both inherit from the Magical Item class. Then you might have certain types of potions. Healing potions, maybe--"Magical Potion of Heal Allies" and "Magical Potion Of Heal Self". So you'd need different classes for those--and so on and so forth.
Inheritance in Javascript can be done a number of different ways and it's possible to get very in-depth, so I'm not going to discuss it in my post. Here are a few useful links to get you started with inheritance, though, if you want to go that route:
Composition
Composition is a concept that borrows heavily from other loosely-typed languages, such as Python, which employs it quite extensively. The basic idea behind composition is that you have a base object class, and whenever you need a certain specific type of object, you add behaviors, or members, to that base class. This isn't quite as well-known as inheritance, but it's definitely the one I prefer.
In Javascript, it works by having a base constructor, Item, and then having other constructors which add the necessary behaviors to your Item. Let's take a look at the example I used for composition--creating a Magical Potion of Heal Allies. You have several distinct properties here: Magical Item, Potion, Healing. With inheritance you'd do something like Item -> Magical -> Potion -> Healing Potions -> Allies
. However, with composition, you can add several behaviors to a base Item class, without having to set up a huge prototype chain: Affect Allies
, Potion
, Healing
.
Since composition is a bit simpler than inheritance (and, I'll admit it, I'm biased) I'll set up a quick example in psuedo-code:
// 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
});
Well, that turned out a bit longer than I expected and probably contains proportionally more errors than I'd like, but I hope that conveys the basic idea of composition.
Now, simpler object creation isn't even the best part of composition, which is that you can re-use different behaviors. Consider you have a magical sword that whenever you make an attack it heals your allies. All you have to do is give it the Healing member and the AffectAllies member and boom--magical sword of heal buddies. With inheritance, you'd have to create a Swords class in the Magical Items class (and then you'd have two different Swords classes-one for Non Magical Swords and the other for Magical Swords! Ew!), then extend that with Healing Swords, and so on and so forth.
You can go either way, inheritance or object composition. Both are equally effective for what you want to achieve.
But what about performance?
200 items with 30 properties a piece? Not a problem. Stick them all in one giant array/object, boil 'em, mash 'em, stick 'em in a stew. The browser don't care. Your best bet is probably an object, though:
var itemList = {
bigSword: new BigSword(...);
smallSword: new SmallSword(...);
}