Monday, March 10, 2008

The Joy of JavaScript

I really like JavaScript (JS). The language strikes a great balance between simplicity and expressiveness. Basically, JS is an awesome little language, especially since the addition of object and array literals (JSON)! I have very mixed feelings about the little I've seen regarding the next major version of JS/ECMAScript. If ever it is available. And widely supported enough to be useful. Let's just say that I'm not holding my breath.

Maybe the new JS will solve a lot of problems (I fear it will be mostly noise added to an otherwise simple language). The problem many of us suffered with for far too long was not the JS language, but the environment: the browser! To some extent that remains true, but with the introduction of Firebug and the Firefox Error Console, JS had come into its own. Now that there are real tools for developers, JS is much more useful. Even the IDE's are recognizing .js files and not just syntax highlighting them, but also finding syntax errors – the bane of JS in the old days.

That said, there are a few things that other languages bring to the table that would be very helpful for JS development in the large. As I see it, the most important things missing from JS are:
  • Namespaces
  • Modules (JS loading JS dynamically)

Others may see things differently, but these are both essentials in my book. I see class-based inheritance as “nice to have”, but I'll try not to digress into that just yet.

The problem with the above list is that only one of these is actually implementable in the language, so I'll focus on that one in a moment. The other one really needs language support to work properly.

In case you haven't guessed it yet, namespaces can be simulated using existing language features. I stress “simulated” because namespaces in C++ and packages (their analogue in Java) are a compile-time scope resolution mechanisms. The goal of a namespace is to reduce name collisions primarily in the global scope. Since JS has no compile-time per se, we'll have to live with what JS can provide: name lookup.

In Java, a fully specified name looks like:

mypkg.subpkg.name

We can achieve this same syntax if “mypkg” were an object containing another object named “subpkg”, etc.. You get the idea. The issue is that namespaces need to be open to extension. This means that the following JS is not quite there:
var mypkg = { subpkg : { name : value } };

It may create the structure above, but what about adding another symbol? If the above approach were used:
var mypkg = { foo : 42 };

We overwrite the previous content of mypkg – not our goal! What is needed is a helper function that can be used the same in both places, that will create the namespace if it does not exist and will not overwrite it if it does. Something like this:
$namespace(“mypkg”); // create mypkg if not already defined
$namespace(“mypkg.subpkg”); // add “subpkg” to mypkg if not already defined
$namespace(mypkg, “subpkg”); // add “subpkg” to mypkg if not already defined

$namespace(mypkg.subpkg, // add items to mypkg.subpkg
{
name : value
});

$namespace(mypkg, “subpkg”, // if mypkg is known to exist
{
name : value
});

$namespace(“mypkg.subpkg”,
{
name : value
});

I've chosen a style that I call a “pseudo-keyword”. The “$” character is not widely used in code, is not used in the standard JS objects or methods and gets your attention like a keyword should. I'll post an implementation of this somewhat flexible method next time.

2 comments:

MrsMama said...

Fascinating!

Don said...

Glad you found it interesting! ;)