Why JavaScript is AWESOME
JavaScript is an awesome language. Now, a few years ago, you’d be marked out as a weirdo for saying something like that. I think there’d probably be some kind of witch-burning ceremony or something, because JavaScript was this stupid language which had stupid syntax and stupid scope and was used to do stupid things by stupid people and just led to awful spaghetti code and killed kittens.
These days people are more understanding, and more and more are coming out of the JavaScript closet. It’s starting to become cool. And I don’t mean cool as in “look at this cool bouncing text” (only works in Internet Explorer 4+ and Netscape 3+); I mean cool as in “hey, check out that cool guy over there writing JavaScript, look how cool he is!”. These days John Resig is a ninja and Douglas Crockford is Chuck Norris.
Seriously though, what’s so great about JavaScript?
Functions or lambdas
A rose by any other name would smell as sweet, and JavaScript’s functions are sweet like chocolate. I tried to explain to a friend recently just what was so great about JavaScript. What I decided was that it was the functions. JavaScript’s functions can act like lambdas, functions and methods. They can be used to create modules, namespaces, classes and objects. A language like Ruby is a toolbox with some really neat little tools that do their job really nicely. JavaScript is a leather sheath with a really really sharp knife inside. That knife can cut anything, and with it you can do anything. You can kill a bear. You can catch fish. You can whittle a piece of wood into a pony. It’s even a toothpick.
So what makes JavaScript functions so great? It’s two things I think: first-class citizenship and closures.
Functions as first-class citizens
Functions are people too you know? Well, no they’re not actually, but they are objects. They can be passed around like any other object. They can be assigned to variables, passed as arguments, and even returned. And because you can write function literals in JavaScript, you can return a function without even naming it:
function outer() {
return function () {
alert("I'm in ur function, accessin' ur local variablez");
};
}
This kind of thing is really powerful. I’m not going to try to give any clever examples because it’s the kind of thing you only truly get once you’ve done it yourself and suddenly the whole universe opens up in your mind.
Closures
A closure is a funny thing to get your head around. If you’re used to a static language, then it just won’t make sense. Really it’s another one of those things that you have to do until you transcend, but I’m going to have a go explaining it.
Closures are intimately related to first-class functions. One of the things you can do with a function in JavaScript is define it within another function. You can nest functions as deep as you like. Here’s an example of a nested function:
function outer() {
var name = 'Bob';
function inner() {
alert(name);
}
inner();
}
So, in this example, when outer
is called, it defines name
and inner
as a local variable and function, respectively (i.e. they are not visible outside of outer
). Then inner
is called, which alerts name
(‘Bob’). That’s not very exciting though - all it shows is that a function can access variables defined in an enclosing scope. But look what happens here:
function outer() {
var name = 'Dave';
function inner() {
alert(name);
}
return inner;
}
var something = outer();
something();
Now outer
is called, and it defines name
and inner
like in the previous example. This time, however, inner is returned (alternatively, I could’ve just returned it as a function literal like earlier). When outer
is called, its return value is assigned to something
. something
is now the same function as inner
. But what happens when we call something
? outer
has returned, so when something
tries to access it it’ll probably segfault or something. Well, no, it won’t. That’s where the magic happens. When inner
was returned, it somehow magically “closed over” its containing scope, essentially keeping it all available even after outer
returned. You can do this with arguments as well:
function outer(arg) {
return function () {
alert(arg);
}
}
outer(5)();
This time the returned function has access to the argument of the outer function. That last crazy line there with all the parentheses isn’t Lisp, it’s JavaScript, believe it or not (Lisp parentheses are nested, in case you ever need to tell the difference). outer
is getting called with an argument of 5
, and then the return value of that call is called itself.
These two things, first-class functions and closures, are what make JavaScript functions so powerful and flexible. Again, this power needs to be felt to be believed, and the only way to feel it is to write it.
Douglas Crockford
Another thing that’s great about JavaScript is Douglas Crockford. He not only wrote the best book on JavaScript - he’s also given the best talks on the language.
Dynamic typing
I’m a big fan of dynamic typing. It adds so much flexibility, agility and speed to programming. It also makes programming much more fun. I’ve written a few posts on the subject so no need to go into more detail here.
Conceptual purity
If I went back ten years and told anyone (myself included) that one of the great things about JavaScript was its conceptual purity, I’d be laughed out of my time machine. But it’s true, there’s something really pure about the language. What can be achieved with such simple language constructs is amazing. There are just objects and arrays (and arrays are just specialised objects). There are literals for objects and arrays. There are functions, and loops. And that’s pretty much it. No classes, no modules, no iterators, no generators, no templates or generics, no macros. None of these things because they just aren’t necessary when functions are allowed to be free as nature intended. You’d think that it would feel limiting not having these features, but it’s actually liberating. It feels clean, and pure. But powerful. Like a polar bear.
Why JavaScript isn’t awesome
There are a few small things that I don’t like about JavaScript (and are generally considered a Bad ThingTM).
Implied globals
If you don’t declare a variable as local with var
, you’re making it global. I don’t need to go into why global variables are a bad thing, because everyone else has.
Semicolon insertion
There was a programme on TV once and they showed all these x-rays with weird things in like toy cars and bottles and stuff, and … oh yeah, semicolon insertion. That’s where the JavaScript interpreter makes it easier for non-programmers to write JavaScript that works and makes it harder for programmers to write JavaScript that’s correct. Silly. Here’s what happens:
return {
javascript : "fantastic"
}; //This will return an object with a single property
//the interpreter sees this as an empty return statement so inserts a semicolon:
return //this line is interpreted as "return;" - with a semicolon
{
javascript : "fantastic"
}; //this is just an empty block now.
But I love it really
It’s easy to mitigate those two things with decent coding practices. Basically, always use var
, always use semicolons where necessary, and always put the opening brace at the end of the previous line, not at the beginning of the next. Finally, put anything you write through JSLint. It’s like a compiler, without the necessity.
Further reading
JavaScript: The Good Parts: This is Douglas Crockford’s book on JavaScript, and it’s brilliant. It’s only 176 pages, but manages to pack a lot into those pages. By the end you’ll know how to write a recursive descent parser for parsing JSON in JavaScript (some really beautiful code).
Move over Java, I have fallen in love with JavaScript: Miško Hevery usually writes great things about testing - here he talks about JavaScript, from the perspective of a Java programmer.
Best resources to learn JavaScript: This is a useful list of resources for learning JavaScript (as suggested by its title).
Structure and Interpretation of Computer Programs: If you still don’t understand what all the fuss is with functional programming, read this book. I’m only half-way through, but it’s already taught me more about programming than any other book. It’s also probably the reason I love JavaScript so much, because deep down, JavaScript is just Scheme in C’s clothing.