HTML Data Port

© 2005 Goetz Heller

Table of Contents Examples Source Code Copyright Note back

Namespaces

Namespaces were conceived to help organize pieces of software and prevent name clashes. Up to and including JavaScript Version 1.5 and the corresponding ECMA specifications, namespaces are not part of the language. They are part of the upcoming JavaScript Version 2.0, however. They help organizing classes so that the global scope is not overly populated by classes; they also can be considered a kind of index. Since namespaces are so useful I decided to implement this feature now. I did it in a way such that future implementations are not compromised; in particular the term "namespace" is not used in the code, and the syntax for referencing elements of a namespace is done via dot notation just as properties and methods of an object are referenced - in fact, a namespace as implemented here is a very simple JavaScript object. Namespaces are brought into life when installing a class which has prepended a chain of nested namespaces to its name.

Maintenance of namespaces is covered by the core module (better said: by the core class) - no separate source code is required. You do not need to - and should not - create namespaces explicitly; they are created on the fly just as needed when classes contained in a namespace need to be installed. And this is how namespaces are implemented: They are just containers for other namespaces and for classes.

Namespaces lie about themselves: If asked via their method isClass() they respond with 'false' whereas classes as we use them say 'true'. The method isNamespace() behaves just the other way round. There is one notable exception: core is treated both as a namespace and a class (in fact it is the single instance of its class which itself is anonymous).

This implementation lacks one feature: There is no using statement to make a namespace a naming context. Of course, you could try using the JavaScript statement with, but this is no complete replacement and generally not recommended. To overcome this, I implemented shortcuts: core.createShortcut() takes the name of a namespace and returns the namespace itself so you can assign it to a local variable. This variable then would be used the same way you would do if you want to abbreviate a lengthy object property chain to save writing effort.

Namespaces should be named according to camelcase convention; this way they always start with a lowercase letter. I recommend naming shortcut variables with capital letters to make it always clear that this is not a global name. It is generally not recommended defining shortcuts globally: self would become quickly overcrowded, and name clashes would be more likely to happen. Of course, it does make perfect sense to install a shortcut in global scope if the namespace for which it stands is used over and over again in many different contexts. In such cases, the string literal used to name the short cut can be used exactliy as you would use namespace name literals, e.g. you could create a shortcut for a shortcut which would not work with local shortcuts (however useful this might be). For instance, if G is a shortcut for the namespace a.b.c, and H is a local shortcut for the same namespace, then 'G.myClass' and 'a.b.c.myClass' are equivalent as classIDs, but 'a.b.c.myClass' and 'H.myClass' are not. The only difference to namespaces then is that the method toString() returns the name of the namespace it designates and not the shortcut name - which is exactly what we want.

It is not recommended that you create namespaces explicitly using your own code. Delegate this task to the core module. It creates namespaces on the fly whenever needed; and namespace creation is only necessary when trying to install a class which resides in a namespace not existing yet, or when creating a shortcut for it. In particular, namespaces are not overwritten by core methods - overwriting a namespace would remove all the classes and namespaces contained in it.