Re: OOP, object literal notation, and the 'new' operator - how to have multiple child objects of a parent object?
- From: "Anthony Jones" <Ant@xxxxxxxxxxxxxxxx>
- Date: Thu, 18 Oct 2007 23:19:33 +0100
"iporter" <isporter@xxxxxxxxx> wrote in message
news:1192714995.047001.28940@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I wonder if anyone can clear up an OOP issue for me, specifically, how
to have multiple child objects of a parent object. Consider the code
below:
var parentObj={
childCount: 0,
childObj: {
id:false,
init: function() {
alert(this.id);
parentObj.childCount++;
this.id = parentObj.childCount;
alert("Child " + this.id + " Created");
}
}
}
Calling 'parentObj.childObj.init();', the first alert produces
'undefined' and the second 'Child 1 Created'. A second call to
'parentObj.childObj.init();' produces the '1' from above instead of
the 'undefined' I'm expecting - I realise this is because I'm working
with the same object.
However, calling 'var firstChild = parentObj.childObj.init(); var
secondChild = parentObj.childObj.init()' produces the same result (as
does 'var firstChild = parentObj.childObj; firstChild.init();).
I've also tried the 'new' operator. But the code 'var firstChild =
new parentObj.childObj;' produces the error 'parent.childObjis not a
constructor'.
Thus, you can see I'm missing the point - can anyone point me in the
right direction?
Your code above shows a level of confusion that its best just to start
again. I suggest you play around with the following code snippets.
Implementing a parent-detail set of objects option 1:-
function Parent()
{
var m_children = [];
this.add = function(id)
{
var child = new Child(id)
m_children.push(child)
}
this.getCount = function() { return m_children.length; }
this.getItem = function(index) { return m_children[index]; }
}
function Child(id)
{
this.getID = function() {return id;}
}
Usage code might look like:-
var parent = new Parent()
parent.add("Hello")
parent.add("World")
alert(parent.getCount())
alert(parent.getItem(0))
alert(parent.getItem(1))
To implement an OOD in Javascript you first need to choose to what degree
you wish to apply the principle of encapsulation in your development.
The above code has good encapsulation. The down side is that each time an
instance is created the methods need to be redefined if an object has
significant number of methods and/or there are to be as signficant number of
objects instanced this can be a bit expensive.
A different approach to implementing the design would be option 2:-
function Parent()
{
this._children = [];
}
Parent.prototype.add = function(id)
{
var child = new Child(id)
this._children.push(child)
}
Parent.prototype.getCount = function() { return this._children.length; }
Parent.prototype.getItem = function(index) { return this._children[index]; }
function Child(id)
{
this._id = id
}
Child.prototype.getID = function() { return this._id; }
The usage code remains unchanged.
Using prototypes means that methods for various types of objects need only
be defined once. This decreases the cost of instancing new objects. It is
also a good basis for implementing an OOD that includes specialization
(inheritance). The down side is that encapsulation isn't too good. The
'private' object state values are exposed albeit with a convention of being
prefixed with _. Still it may be tempting to some consumer of the object to
access these values directly rather than using the accessor functions.
Another approach is similar to the above where encapsulation is simply
abandoned Option 3:-
function Parent()
{
this.children = [];
}
Parent.prototype.add = function(id)
{
var child = new Child(id)
this._children.push(child)
}
function Child(id)
{
this.id = id
}
Now the usage code looks like:-
var parent = new Parent()
parent.add("Hello")
parent.add("World")
alert(parent.children.length)
alert(parent.children[0])
alert(parent.children[1])
However abandoning encapsulation like the above is so far removed from OOD
that I doubt it would qualify to be call OOD (although specialization may
still be implemented).
My preferred approach is Option 2 but I often match the approach to the
requirement using Option 1 at times and very occasionally I might consider a
little bit of Option 3.
--
Anthony Jones - MVP ASP/ASP.NET
.
- References:
- Prev by Date: Re: Problem with javascript in web page.
- Next by Date: Re: Problem with javascript in web page.
- Previous by thread: OOP, object literal notation, and the 'new' operator - how to have multiple child objects of a parent object?
- Next by thread: Problem with a regular expression
- Index(es):
Relevant Pages
|