I’ve previously berated JavaScript for being crap.

I’ve been using it quite a lot lately and I was in fact mistaken. JavaScript is not crap. JavaScript is mediocre, but it has a few redeeming features like the clever stuff you can get up to if you nest functions. In Java if you want to write, say, a straightforward recursive descent JSON parser you’ll probably have to define a class with 10(ish) private methods and one public method. If you want to do this in JavaScript you’ll write one global function and inside it you’ll have ten nested functions. Those nested functions are entirely private; not because you explicitly set them so, but because you defined them in a scope which isn’t visible to any code outside. The nested functions inherit their parent function’s scope, too, so they can read and write variables in the parent. This is just neat.

As well as, you know, understanding it better, one of the other things that makes it more usable is having a proper build routine. I’ve been using the yui-compressor in place of a compiler but I’ve recently switched to the Google Closure Compiler (nice acronym, guys). YUI has basic syntax checking but Closure is, well, it’s not actually a compiler but it’s not far off. There’s also JSLint which you might want to incorporate into a build routine but I’ve found it to be a waste of time*. The cool thing about Closure is that not only does it do the basic syntax checking for stuff like mismatched braces, but it also tries to account for things like function calls and checks that these functions exist and you’re using the right arguments and so on. You have to use extern files to let it know what methods should exist on what objects, these are basically your header files. You write them by defining symbols/functions (not implementing them) and using a Javadoc-like syntax to say what they are. Even though JavaScript is dynamically typed, you can get quite a lot of type-checking at compile time with this.

Their SVN repository has a bunch of useful community written extern files, most notably for jQuery:

use them with –externs FILE

you can also set a highly advanced ‘optimisation’ flag, but I don’t recommend it as it will probably break your code. I only played briefly with it but my impression was if you’re compiling a library then you probably shouldn’t use it because code that uses that library (think dynamically links) probably won’t work. On the other hand if you’re compiling your entire project all at once, including libraries (think static linking) it should be more resilient. That was my impression, I may be wrong. In any case it doesn’t seem worth the effort to rewrite your code to make it work. The default optimisation flag is comparable to yui and usually up to 10% better.

yui is pretty naive in what it actually does. Closure is a lot cleverer, things like…

var cmp = function(a, b) {
  if (a > b) return 1;
  else if (a < b) return -1;
  else return 0;

yui will take this to:

var cmp=function(h,g){if(h>g){return 1}else{if(h<g){return -1}else{return 0}}}

which hardly seems worth the effort. Whereas Closure is smart and realises it can be written more concisely with nested ternary operators:

var cmp=function(d,i){return d>i?1:d<i?-1:0}

Although it also does some fairly strange things, like it will happily remove all your string variables and replace them with literals. So if you declare var classname = ‘someclass’; at the top and use a few $(..).toggleClass(classname);s, expect to see them all ‘compiled’ to $(..).toggleClass(“someclass”).

*because it frequently halts at what it calls an error, which you have to fix before it will continue checking the source. Unfortunately, half the stuff it identifies isn’t an error at all; it’s a fairly specific set of style guidelines which I have no desire to follow. The one that irks me most is the fact it complains about usage of ‘continue’; I *hate* the philosophy that you should avoid all jump statements and instead end up nested 5 levels deep in unfathomable mazes of ‘if else’. That is not readable! You already end up indented 5 or 6 levels deep with closures and whatnot, don’t make the problem worse. JSLint even suggests wrapping the whole of a for x in y loop in an if statement instead of negating the condition and continuing. If you wrap THE WHOLE of one block inside another block, something is wrong.


I like blogging

Posted in Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: