Professional JavaScript | 3 | WebReference

Professional JavaScript | 3

[previous] [next]

Professional JavaScript

Aggregation / Containment

Aggregation and containment in object-oriented terms mean the ability to store objects entirely inside other objects. As you've seen from Chapter 2, there is some simple syntax to do this. Here's an example:

var apple = new Object(); var pear = new Object(); var peach = new Object(); var fruitbowl = new Object(); fruitbowl.item1 = apple; fruitbowl.item2 = pear; fruitbowl.item3 = peach;

The last object, fruitbowl, has several properties that are themselves objects. Aggregation/containment isn't much different to encapsulation in this respect; it's just that whole objects are collected together into another object rather than object parts collected together into a single object. As before with encapsulation, you could worry about hiding the contained objects, but it's much easier just to relax. However, in this case you can get too relaxed as this further example shows:

var pickle = new Object(); object3.flavor = "extra tart"; pickle_jar1.contents = pickle; pickle_jar2.contents = pickle;

Lines 1 and 2 are fair enough encapsulation – an object with a single property is created. But in lines 3 and 4 both pickle jars (assumedly they're objects) are (also assumedly) trying to contain the pickle. This is not allowed as only one object can contain another. 100% of one pickle won't go into both of two pickle jars. Okay, you could put the pickle in one jar and that jar inside the other jar, but that's a different script. That script would actually be an example of association which we'll come to later.

The example illustrates that JavaScript supports aggregation/containment, but doesn't enforce it. Using a loosely-typed language lets you relax, but on the other hand it's up to you to make sure you don't confuse yourself. Lines 3 and 4 illustrate association, not encapsulation, aggregation or containment. When the conceptual idea separates from the things that the language lets you get away with, that's when C++ and Java programmers get excited and say that JavaScript only has "weak" (as opposed to "robust") support for OO. But as a relaxed scripter, who cares – as long as you accept the onus is on you to be clear about your design.

In an object oriented language: the peach is part of the fruitbowl, the fruitbowl contains a peach, or has a peach (sometimes officially written HAS-A).

Aggregation and containment are probably the most interesting object-like features to the scriptwriter. The reason is that Web browsers that host JavaScript have a large containment hierarchy (objects containing objects containing objects).


Inheritance in object-oriented terms means that an object's nature or essence or features come in part from itself, and in part from another object. It inherits the other object's features. That other object might be in the same position – in part described by itself and in part from a third object. In that case, the first object is also in part from the third. Objects can't be mutually derived from each other. Since there is a one-way order, the collection of interrelated object features is called an object hierarchy. Notice that the discussion focuses on object features not object instances. Features are descriptive of an object. An instance represents an actual object.

A classic example of inheritance comes from geometry:


Here is a generic polygon, a polygon that is a rectangle, and a polygon that is a rectangle that is also a square. It's easy to see that rectangles inherit features from polygons. Polygons have a number of straight-edged sides that completely enclose a space and so do rectangles. However rectangles have some properties of their own as well: they must also have exactly 4 sides; opposite pairs of sides must be the same length; and all angles between adjacent sides must be 90 degrees. Further, it's true that squares fulfill all the rectangle criteria, so they can be said inherit the rectangle's features. Squares also have features uniquely their own. Not only must opposite sides of a square match in length and all angles be 90 degrees, but all sides must be equal in length as well.

The square depicted doesn't partially exist as part of the polygon depicted – clearly they are separate objects. It's just that the features of the more general polygon contribute to the features of the square. Sometimes you look or sound like one of your parents, but you're still yourself.

A bit of inheritance language: you can say squares inherit from rectangles. Squares are also the derived thing and rectangles are the base thing. Alternatively, squares are the child thing and rectangles the parent thing. It's also very common and expressively powerful to say "a square is a rectangle". This is sometime written IS-A to emphasize the specialized nature of the relationship. You can also say that a square specializes a rectangle, or that a rectangle generalizes a square.

For completeness, consider triangles. Triangles are polygons, but they're not rectangles. So it's possible for one base object type to have two different derived object types. The different derived object types are unrelated to each other. Such collections of inheritance relationships can be drawn like this:


This is an inheritance hierarchy where the arrows point towards the parent. A popular notation for object modeling diagrams is UML, which you can read more about in Instant UML by Pierre-Alain Muller (Wrox Press, 1997. ISBN 1-861000-87-1).

JavaScript Prototype Chains

Inheritance can get pretty complex, so the way JavaScript handles it is deferred until all the other object oriented concepts are disposed of. Nevertheless, it should be easy to see that prototype chains are a good candidate for inheritance-type behavior in JavaScript, since an object appears to have all the properties of its prototype object. Alas, if only it were that simple. Organizing JavaScript inheritance is left to the next main section in this Chapter because there are a number of options to consider.

[previous] [next]
Created: February 5, 2001
Revised: February 5, 2001