Packaging / Namespacing JavaScript

D

Dan Webb

Hi All,

Im currently working on ways of pacakaging javascript
functions/variables/objects in a similar way to the Java package
statement so that scripts can be interact with each other with the
minimum risk of clashing (due to function/variable name clashes). Do
any of you do this already and/or are there any techniques you've come
across?

Im aware that ECMAScript 2 has this facility and have seen several
scripts that use some thing like this:

var com = [];
com.test = [];
com.test.isValid = function() {
....
}

com.test.isValid();

so the only entry point to there scripts is through the com and test
objects but this is rather primative and can be easily accidentally
overwritten by other scripts. Anyone thought much about this?

Any feedback or opinions would be much appreciated...

Cheers,

Dan Webb
http://www.danwebb.net
 
R

Richard Cornford

Dan said:
Im currently working on ways of pacakaging javascript
functions/variables/objects in a similar way to the Java package
statement so that scripts can be interact with each other with the
minimum risk of clashing (due to function/variable name clashes). Do
any of you do this already

Keeping things out of the global namespace; Yes, religiously (and beyond
what is strictly necessary), using closures. Attempting to implement
something analogous to Java's packages in javascript: no.

Packages are collections of classes and while they will tend to be
interrelated (and interdependent) the act of grouping them into a
package implies a desire to have the whole lot available in one chink
(or not available at all). For client side scripting everything that is
to be executed on the client has to be sent to the client so it is most
efficient to only send the code that will be needed for the specific
task. The diversity in possibilities that would be appropriate in a Java
package would result in the downloading of unnecessary code if
implemented for client-side scripting (or the weeding out of classes
that were not needed in a specific context, which would seem to defeat
the purpose of the packaging).
and/or are there any techniques you've come across?

I assume you have read:-

<URL: www.litotes.demon.co.uk/js_info/private_static.html >

- and its short discussion on grouping related constructors/classes
within the same closure. Though I don't see that addressing the concerns
you mention below (and it is not a possibility that I have seen the need
to implement myself (beyond grouping private constructors/prototypes
with single public constructors which were the only code that needed
access to the private classes).
Im aware that ECMAScript 2 has this facility and have
seen several scripts that use some thing like this:

var com = [];
com.test = [];
com.test.isValid = function() {
...
}

It looks to me like the Array literals should be object literals (and
nested in their definition):-

var com = {
test:{
isValid:fucntion(){
...
}
}
};
com.test.isValid();

so the only entry point to there scripts is through the com and test
objects but this is rather primative and can be easily accidentally
overwritten by other scripts.

I don't think you could fairly describe it is "easily accidentally
overwritten". Obviously the property name "com" is vulnerable to naming
collisions but that is because it is short and simple. A package naming
convention of something like -
longPackageDescription.groupName.featureName - would be less prone to
naming collisions (so, abandoning any attempt to mirror Java's specific
naming scheme). But, with the exception of the very few scripts that can
be implemented totally anonymously, all scripts must be in some danger
of accidental interactions resulting form naming collisions. Putting
anything in the global namespace gives another script the opportunity to
overwrite it. The best that can be done is to limit the impact of a
script on the global namespace as much as possible, and hope the author
of the other scripts has the sense to do likewise.

To some extent there is no choice but assuming some competence (or at
least awareness of the issue) on the part of the authors of those other
scripts (common evidence to the contrary not withstanding).
Anyone thought much about this?
<snip>

I have thought about it a lot over the last couple of years. We are
really taking about strategies for code re-use; not having to re-write
everything (or even much) for any new project. There was a time when I
thought that general libraries (which your packages will represent) were
a good idea, but I have been forced to abandon that notion and am now
convinced that re-usable code should be pitched at a relatively
low-level in isolated components.

Richard.
 
D

Dan Webb

Yes, I think you are right really. There will always be some impact
on the global namespace that could cause problems and limiting it is
best done by using closure as outlined in the article you posted. As
you may notice from my blog thanks to you I've recently discovered
those techniques by reading your FAQ article on jibbering.com which
was nothing short of revolutional to my JavaScript coding (Thanks!).

My idea is that by having a package style system you are imposing a
convention as well as limiting impact on the global namespace. What
I've developed is a simple namespace() function. This basically takes
a package name then builds the correct objects if necessary (but only
if necessary) so

namespace("net.danwebb.util").isValid = function() {
....
}

would evaluate to net.danwebb.util but then if you declared a function
to a different namespace like:

namespace("net.danwebb.event").anotherFunction = function() {
}

then this would only build the objects that weren't created. With
this convention in place scripts would all fit within the heirarchy
and should keep the namespace quite clean.

I too don't agree with monolithic generic scripts but over the years
I've built up tons of random scripts and often need to apply them in
various combinations on the same pages and this is where the idea was
born. Also, before Flash MX 2004 I saw alot of utility in producing
large general purpose libraries (as filesize isn't an issue) and alot
of problems with namespacing when working on large projects.

An example script packaged in this way is something like this:

http://www.danwebb.net/tests/slideshow/event.js

which is a little set of event handling things I wrote which fits in
with several other scripts into this:

http://www.danwebb.net/tests/slideshow/

(Which is very much work in progress and pretty dodgy at the moment so
don't tear it apart just yet :) ) But you should get what Im aiming
at.

Do you think there's any milage in this at all? Im half quite into
the idea but also have alot of the same doubts as you outline in your
reply. Ive been thinking about it a bit too much and have lost a bit
of perspective. Perhaps all the Java I've been doing recently has
left me trying to Javatize my JavaScript (Which is definately almost
always a wrong 'un).

Thank for your feedback though Richard, much appreciated.
 
D

Dan Webb

Yes, I think you are right really. There will always be some impact
on the global namespace that could cause problems and limiting it is
best done by using closure as outlined in the article you posted. As
you may notice from my blog thanks to you I've recently discovered
those techniques by reading your FAQ article on jibbering.com which
was nothing short of revolutional to my JavaScript coding (Thanks!).

My idea is that by having a package style system you are imposing a
convention as well as limiting impact on the global namespace. What
I've developed is a simple namespace() function. This basically takes
a package name then builds the correct objects if necessary (but only
if necessary) so

namespace("net.danwebb.util").isValid = function() {
....
}

would evaluate to net.danwebb.util but then if you declared a function
to a different namespace like:

namespace("net.danwebb.event").anotherFunction = function() {
}

then this would only build the objects that weren't created. With
this convention in place scripts would all fit within the heirarchy
and should keep the namespace quite clean.

I too don't agree with monolithic generic scripts but over the years
I've built up tons of random scripts and often need to apply them in
various combinations on the same pages and this is where the idea was
born. Also, before Flash MX 2004 I saw alot of utility in producing
large general purpose libraries (as filesize isn't an issue) and alot
of problems with namespacing when working on large projects.

An example script packaged in this way is something like this:

http://www.danwebb.net/tests/slideshow/event.js

which is a little set of event handling things I wrote which fits in
with several other scripts into this:

http://www.danwebb.net/tests/slideshow/

(Which is very much work in progress and pretty dodgy at the moment so
don't tear it apart just yet :) ) But you should get what Im aiming
at.

Do you think there's any milage in this at all? Im half quite into
the idea but also have alot of the same doubts as you outline in your
reply. Ive been thinking about it a bit too much and have lost a bit
of perspective. Perhaps all the Java I've been doing recently has
left me trying to Javatize my JavaScript (Which is definately almost
always a wrong 'un).

Thank for your feedback though Richard, much appreciated.
 
D

Dan Webb

Yes, I think you are right really. There will always be some impact
on the global namespace that could cause problems and limiting it is
best done by using closure as outlined in the article you posted. As
you may notice from my blog thanks to you I've recently discovered
those techniques by reading your FAQ article on jibbering.com which
was nothing short of revolutional to my JavaScript coding (Thanks!).

My idea is that by having a package style system you are imposing a
convention as well as limiting impact on the global namespace. What
I've developed is a simple namespace() function. This basically takes
a package name then builds the correct objects if necessary (but only
if necessary) so

namespace("net.danwebb.util").isValid = function() {
....
}

would evaluate to net.danwebb.util but then if you declared a function
to a different namespace like:

namespace("net.danwebb.event").anotherFunction = function() {
}

then this would only build the objects that weren't created. With
this convention in place scripts would all fit within the heirarchy
and should keep the namespace quite clean.

I too don't agree with monolithic generic scripts but over the years
I've built up tons of random scripts and often need to apply them in
various combinations on the same pages and this is where the idea was
born. Also, before Flash MX 2004 I saw alot of utility in producing
large general purpose libraries (as filesize isn't an issue) and alot
of problems with namespacing when working on large projects.

An example script packaged in this way is something like this:

http://www.danwebb.net/tests/slideshow/event.js

which is a little set of event handling things I wrote which fits in
with several other scripts into this:

http://www.danwebb.net/tests/slideshow/

(Which is very much work in progress and pretty dodgy at the moment so
don't tear it apart just yet :) ) But you should get what Im aiming
at.

Do you think there's any milage in this at all? Im half quite into
the idea but also have alot of the same doubts as you outline in your
reply. Ive been thinking about it a bit too much and have lost a bit
of perspective. Perhaps all the Java I've been doing recently has
left me trying to Javatize my JavaScript (Which is definately almost
always a wrong 'un).

Thank for your feedback though Richard, much appreciated.
 
L

Lasse Reichstein Nielsen

My idea is that by having a package style system you are imposing a
convention as well as limiting impact on the global namespace. What
I've developed is a simple namespace() function. This basically takes
a package name then builds the correct objects if necessary (but only
if necessary) so

namespace("net.danwebb.util").isValid = function() {

How does the namespace function work, exactly? You have one included
in event.js, but it takes a second argument (or is that optional, it's
not written for readability :). It seems you store the objects name
spaces in the global object.

From your description, I would code it something like:
---
function namespace(name, obj_opt) {
var names = name.split(".");
for(var i = 0, base = namespace; i < names.length; i++) {
var n = names;
if (i == names.length - 1 && obj_opt) {
base[n] = obj_opt;
} else if (!base[n]) {
base[n] = new Object();
}
base = base[n];
}
return base;
}
---
(I'm storing the namespaces as properties of the namespace function
itself, to make sure I don't affect the global object more than
necessary).


However, is there any reason for creating three objects instead of
just one? I.e.:
---
function namespace(name, obj_opt) {
return namespace[name] = (obj_opt || namespace[name] || new Object());
}
---
As long as you don't traverse the namespace hierarchy manually,
and only use the "namespace" function for access, the effect will
be the same, and fewer objects will be created (although with longer
property names);

/L
 
R

Richard Cornford

Dan Webb wrote:
... . As you may notice from my blog ...

I had noticed, but mostly because I had noticed a recent more
wide-spread interest in javascript closures and was back tracing links
to the FAQ page through google to see the extent to which I was
responsible for it.

(Thanks!).

You are welcome. I am glad I was able to explain closures effectively,
though my explanation concentrates on the structures of objects involved
(because I tent to think in OO terms), there will be other styles of
possible explanation, perhaps better suited to programmers with other
backgrounds.
My idea is that by having a package style system you are imposing
a convention as well as limiting impact on the global namespace.
What I've developed is a simple namespace() function. This
basically takes a package name then builds the correct objects
if necessary (but only if necessary) so

namespace("net.danwebb.util").isValid = function() {
...
}

would evaluate to net.danwebb.util but then if you declared a function
to a different namespace like:

namespace("net.danwebb.event").anotherFunction = function() {
}

then this would only build the objects that weren't created.
With this convention in place scripts would all fit within
the heirarchy and should keep the namespace quite clean.

I cannot argue that the result would not separate namespaces. I am still
not sure that "net" or "com" or whatever are good names for the point of
contact with the global namespace. "net_danwebb" or "danwebb_net" would
be a lot safer, but would mean abandoning the Java style package naming
scheme. However, the familiarity of the naming scheme to Java
programmers is not necessarily enough to justify its use as _the_ naming
scheme. If establishing a convention is a good idea (and it certainly
could be) does it have to be that precise convention? I suppose it would
be a matter of deciding what purpose the convention was supposed to
serve; if it was just the matter of separating namespaces then that can
be satisfied without a rigid adherence to the Java package naming
pattern.

Because I work with JSP quite a lot I actually don't want my javascript
code to be too similar to my Java code. One of my conventions is to use
single quotes for all javascript strings so my JSP (Java and javascript)
syntax highlighting colors them like Java character literals, giving the
Java code a tendency to be full of chunks of red while the javascript
code is littered with equivalent chunks in orange. Giving an immediate
visual distinction between the two languages and saving looking twice
(or closely) to see what is what.
I too don't agree with monolithic generic scripts but over
the years I've built up tons of random scripts and often
need to apply them in various combinations on the same pages
and this is where the idea was born.

Code re-use is such an obviously good idea that it deserves some
consideration of what would qualify as a 'best practice'. (Though a best
practice for someone with an OO mindset might not be well suited to a
more procedural approach.)

To date discussions on the subject have definitely come down against the
use of large cross-browser API libraries but there hasn't been much in
the way of specific proposals about what could be done instead (in the
sense of strategies and/or conventions).

Probably what is needed is for there to be a number of reasonably well
formed proposals of strategies or conventions for code re-use so they
all could be subject to public discussion and an assessment of their
relative merits.

For my own approach I don't think I am ready for that yet. I have a good
feel for what I am actually doing in terms of creating low-level
components as the re-usable units in script authoring but I wouldn't
expect to be able to convince anyone else (or be properly exposed to
valid criticism) until I can create a formal explanation of my strategy.
My experience is that it will take me at least two or three attempts
before I can get things clear enough in my own mind to do a reasonable
job of formally explaining the concepts to others. I am simply not there
yet (and may yet spot a fatal flaw or inconstancy that completely
undermines the idea).
Also, before Flash MX 2004 I saw alot of utility in producing
large general purpose libraries (as filesize isn't an issue)
and alot of problems with namespacing when working on large
projects.

An example script packaged in this way is something like this:

http://www.danwebb.net/tests/slideshow/event.js

which is a little set of event handling things I wrote which
fits in with several other scripts into this:

http://www.danwebb.net/tests/slideshow/

(Which is very much work in progress and pretty dodgy at the moment so
don't tear it apart just yet :) ) But you should get what Im aiming
at.

OK, I won't say anything about the scripted web page, beyond saying that
it generally seems very optimistic about that capabilities of the client
browsers it encounters (I tend to perceive a need to be very defensive
and cautions about the capabilities of browsers).

The event.js makes sense as a package, it is not where I would have
drawn the abstraction but its contents seem to have a reasonable
cohesion. I can also understand util.js as a package because I would
expect that to contain whatever was left over, though one more
query-string/URL method and they probably should be moved out to an
object of their own.

However, slide.js seems to represent the non-re-used code specific to
the application and I don't see that as needing to be deployed within
one of your 'package' structures. Indeed because that function
(constructor?) assigns an onload handler and creates and inserts its own
control elements into the document, it would be possible to implement
the slideshow aspect of the script totally anonymously. Making it
invulnerable to naming collisions.
Do you think there's any milage in this at all?

I don't think we have reached the point where I would dismiss this out
of hand. I don't really like the need to be re-resolving long property
accessors every time any functionality form the 'packages' is used (or
the adherence to the Java naming style) but I would like to know more
about the criteria applied in the design decisions. I like to see a
problem clearly and fully identified.
Im half quite into the idea but also have alot of
the same doubts as you outline in your reply.
Ive been thinking about it a bit too much and have lost
a bit of perspective.

One of the advantages of a public debate is that you get many
perspectives (good, bad and indifferent).
Perhaps all the Java I've been doing recently has
left me trying to Javatize my JavaScript (Which is
definately almost always a wrong 'un).

I have seen some really stupid things done in the name of making
javascript more like Java (in the way it is used), but I usually think
it is worth considering why these attempts to javatize javascript are
created. For example, I have seen attempts to implement javascript
'classes' in a Java style (such that the entire class definition is
wrapped in braces as Java class definitions are) that were horribly
inefficient in their implementation (with lots of unnecessary function
(and other) objects being created on each instantiation. But the desire
to turn javascript's rather diffuse 'class' definitions into a more
distinct unit of code makes sense to me, and should be good for code
maintenance, so I would be satisfied with the same idea in a more
efficient implementation.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top