I'm currently facing a tricky problem which I am not able to solve in javascript. I have a function object Unit
for example. This is the base object.
There are two function objects Tank
and AirDefense
which are prototypal inheriting from Unit
A "child" of Unit
has two properties level
(normal integer) and damagePerSecond
(an array of integers where the index represents the level and the value the damage per second on that level).
level
should be a "static" property, so whenever I change the level of an instance of AirDefense
or Tank
every instance of it that was previously created must be updated and apply the changed level
However there also should be an interface to change the level statically, so that I don't have to call the setLevel
method on a concrete instance but rather on the function object itself.
The problem is that I am implementing a method called getDamagePerSecond()
which returns the damage per second for the current level. But the current level of the concrete child object is not known by the parent.
I cannot use a static property on the base object because it would set the level for both objects Tank
and AirDefense
but the levels should be seperated for each of those child objects.
tl;dr: I want to use a child objects static property from the parent object, but I don't know the child in the parent object yet.
I'll provide what I have tried so far to clear up how these objects work together.
Unit
function Unit(){
this.level;
this.damagePerSecond;
}
Unit.prototype.getDamagePerSecond = function(){
return this.damagePerSecond[this.level];
};
Unit.prototype.getLevel = function(){
return this.level+1;
}
Tank
function Tank(){
this.level = Tank.level || 0;
this.dps = [5,10,15];
}
Tank.prototype = new Unit();
Tank.setLevel = function(level){
Tank.level = level-1;
}
AirDefense
function AirDefense(){
this.level = AirDefense.level || 0;
this.dps = [1,5,9];
}
AirDefense.prototype = new Unit();
AirDefense.setLevel = function(level){
AirDefense.level = level-1;
}
Main (Correct Result)
Tank.setLevel(5);
var t = new Tank();
var a = new AirDefense();
console.log(t.getLevel()); //outputs 5
console.log(a.getLevel()); //outputs 1
Main (Wrong Result)
var t = new Tank();
Tank.setLevel(5);
var a = new AirDefense();
console.log(t.getLevel()); //outputs 1 - should be 5
console.log(a.getLevel()); //outputs 1
What I basically did was to fake static properties in the concrete objects. Level is a static property on my child object. During instantiation I have an additional instance property with the level which will be set to the value of the fake static property.
But there are several problems arising here:
I can only set a level for an object type before it is instantiated. But I want to change the level of both, all objects that are already instantiated and those that will be in the future.
Using this approach I need to implement a
setLevel()
method on all of my child objects. I think this is the opposite of dry.By providing a static interface it is impossible to directly message concrete instances that do already exist
If I used terms that are not usual when speaking about prototyping I'm sorry for that. I come from languages that have a classic OO-approach.
I'm not that familiar with prototypal inheritance just yet, so I hope somebody can give me a wink into the right direction.