Sunday, December 2, 2012

Closure could be a bit more javascripty

My new years resolution for this year has been to take javascript more seriously. In that time, one of the things that has caught my attention (and affection) has been the closure compiler.

I do love closure, I do but as it is now, it can't really think of itself in a universe where one would write code that would _ever_ be executed uncompiled.

Until there is a (working) realtime compilation plugin for Eclipse, I'm going to need to run my JS uncompiled until I get it right, and then compile it.

Consider the following two types: ns.Type1 and ns.Type2.

var ns = {};
(function() {

 /** @constructor  */
  ns.Type1 = function() {
  };
  
})();

/** @constructor  */
ns.Type2 = function() {
};

/**
 * @param{ns.Type1} bar
 */
function foo(bar) {
}

/**
 * @param{ns.Type2} bar
 */
function baz(bar) {
}


They only differ in that ns.Type1 is created inside a closure. This lets you have actually private variables in javascript and generally allows for the sort of encapsulation that javascript should have had built into it. The second one, just defines everything out in the global namespace.

Everything works great for Type2. For Type1, you get a warning (and a failure) for attempting to reference the type in @param{ns.Type1} in your function at the bottom.

If you are always going to run your code compiled with ADVANCED_OPTIMIZATIONS, it really doesn't matter. You'll define your privates private with annotations and any illegal usage is going to fail compilation. Thats great. Except if you do your development and debugging in naked JS, you won't find these problems until you compile.

Is that a bug? Hard to tell: I suspect, given what I've read from the closure discussion groups, that this sort of thing was designed in.

And it gets worse, the further you go off the reservation. Consider Crockford would have us believe (and I am pretty sure he is right, at least I'm not sure he is wrong and he is smarter than me) that we would do well to define our functions for our Types in their constructor. Thats great, but in both cases there seems to be no way to tell the compiler that your Types expose various properties.

At any rate, I love closure. It makes for better javascript, but it could go a long ways towards making better javascript easier by simply adopting some of the best practices that have evolved over the years for making javascript safter without compilation. As an added benefit, these sort of things would make it much easier to make tools like jQuery compile with ADVANCED_OPTIMIZATIONS.





No comments: