I am doing Object Oriented programming in JavaScript without Prototype/jQuery (I use jQuery for other stuff). It has been working fine so far, but I ran into an issue with inheritance. Basically, when I declare objects in a constructor, they are shared between instances. Below is some sample code:
A = function()
{
this.y = new Array();
}
A.prototype.doStuff = function(n)
{
this.y.push(n);
}
B = function()
{
}
B.prototype = new A();
var b1 = new B();
var b2 = new B();
b1.doStuff(100);
b2.doStuff(200);
console.log("b1:");
console.log(b1);
console.log("b2:");
console.log(b2);
This outputs an array [100, 200]
for both b1
and b2
. What I want is for b1
and b2
to have their own, separate arrays for y
. How do I go about this?
(PS. I assume that Prototype's class system has something built in for this. However I would rather not rewrite a bunch of my code to use that class system)
The problem is that your A
constructor function is only run once for all B
instances, and so this.y
is a reference to just one array. Any reference to it from B
will be resolved via the prototype chain to the single, central A
reference, which only has one y
. This is a very useful feature, just not for what you're trying to do here.
The answer is to separate construction from initialization; the constructor sets up central resources and the initializer initializes an instance. This is how the issue is handled by most of the "class" implementations I've seen for JavaScript. For that to work, you have to provide a means for each level in the hierarchy to call the previous level's initializer (which is useful for other methods as well) -- e.g., supercalls.
Supercalls are why you're probably better off using something like Prototype for this: They're hard to do well, and it's very easy to fall into the "grandchild" problem -- a solution that seems to work, but ends up only working with a Parent<-Child structure, not a Parent<-Child<-GrandChild structure.
However, if you're going to do your own inheritance mechanism, this post on supercalls from my pathetically-anemic blog may be helpful as I go into some of those issues in depth. It takes a simplified version of Prototype's inheritance mechanism, deconstructs it a bit, and talks about a way to do supercalls that doesn't have some issues I have with Prototype's current supercalls. That may help you with doing them in your own mechanism.
B.prototype = new A();
this creates only one instance of A for every B.
You might consider doing sth like
B = function()
{
this.$super = new A();
}
B.prototype.doStuff = function()
{
return this.$super(args);
}
C = function ()
{
this.$super = new B();
}
C.prototype.doStuff = function()
{
return this.$super(args);
}
C.prototype.whoIsMyGrandParent = function()
{
return this.$super.$super;
}
Javascript has NO real inheritation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With