Beware of JavaScript semicolon insertion
One of most tricky behaviors by JavaScript interpreters is semicolon insertion.
Why semicolon insertion?
Unfortunately, semicolons are optional in JavaScript, which leads to developers being sloppy, using them in some places, while omitting them elsewhere. “Luckily”, JavaScript interpreters take this into account, and at runtime, insert semicolons where it thinks it should be one.
Good and bad code style examples
So, how is this a problem? Let’s start by taking a look at the below code:
// Good
return {
javascript : "fantastic"
};
// Bad!
return
{
javascript : "fantastic"
};
The problem
So, I’m sure some of you wonder what the hell’s wrong with having the opening curly bracket on a new line? You love that coding style and it all becomes clearer. The answer is semicolon insertion. The bad code is interpreted like this:
return; // Semicolon inserted, believing the statement has finished. Returns undefined
{ // Considered to be an anonymous block, doing nothing
javascript : "fantastic"
};// Semicolon interpreted as an empty dummy line and moved down
My advice
Since it does matter where you put the curly brackets, my strong recommendation is to use the opening one at the end of the line, preceded by other code. Also, make sure to always put semicolons in your code, to avoid potential problems.
Acknowledgements
I first saw this lovely example being presented by Douglas Crockford at @media Ajax 2007 (my report), and my pal Remy presented it in his blog. I just wanted to re-iterate the point here, since a lot of people doesn’t seem to know about semicolon insertion.
16 Comments/Reactions
October 16th, 2008 at 17:26
For anyone interested in the impact of running this code – here’s a working demo of why you should format your code properly: http://jsbin.com/azufi
October 16th, 2008 at 19:31
For those that use Textmate, there is actually a little bundle, that goes a long way.
It’s called JavaScript Tools, was originally written by Andrew Dupont, and has since been adopted and moved to bundleforge.
http://bundleforge.com/
For me, the most interesting feature of the bundle is that it runs your javascript through jsLint every time you save the files.
That will give you immediate feedback on bad coding style, missing semicolons, etc.
October 16th, 2008 at 19:34
Or for an even more updated version, get it from github:
http://github.com/subtleGradient/javascript-tools.tmbundle/tree/master
October 16th, 2008 at 19:38
That and other things is noticed when you slap your code into lint http://jslint.com/
October 16th, 2008 at 19:39
Remy,
Great, thanks!
Morgan,
Thanks for the tip! Personally, I use that bundle in TextMate, and it sure saves me some problems at least.
icaaq,
Absolutely!
October 16th, 2008 at 19:43
Personally, I avoid returning object declarations. If a function is meant to return data, I’d rather set it to a variable and then return the variable. This ensures that the return statement is the last line of the function, aiding overall readability.
October 16th, 2008 at 19:50
Just last week I created a pre-commit hook for SVN, that prevents me from commiting .js files with “console.” in them.
Perhaps I should just expand that to run my stuff through jsLint as well.
October 16th, 2008 at 19:58
Jonathan,
Yes, I know that you prefer that style (I don’t).
But also, there are JavaScript approaches, such as the Yahoo Javascript Module Pattern, which relies on returning an object.
Besides, someone like you know the ins and outs of JavaScript, so you when things will break and when not. My take is that most people don’t, so personally, I’d recommend using the opening curly bracket on the same line as the code.
Morgan,
Well, maybe. JSLint is very good overall, but it might complain about something which you’d deliberately want that way, and it feels a bit counter-effective to demand JSLint validation in those cases.
October 16th, 2008 at 20:58
Robert,
It is possible to pass options to the lint, to tell it what to bitch about, and what not… but I do see your point, and some of the “complaints” might not be obvious for the less experienced JavaScript programmer… and this will just increase frustration without necessarily increasing quality of code.
But then again, I hate warnings (or broken windows) as much as the next developer, so if I am Lead, you’re just going to have to deal with the harsh rules
October 16th, 2008 at 21:40
Great tip on the TextMate bundle, Morgan. I wish Panic would implement something similar into Coda. Maybe we can hope for something good in MacRabbit Espresso?
Robert, you might consider JavaScript Lint in favor of JSLint. I used to whole heartedly stand by JSLint, but more and more it seemed like Douglas Crockford either making a point or being strict beyond the point of practicality. For example, in
forloop declarations, JSLint will throw an error for using the increment operator. Crockford has a valid reason for this: it’s hard to read code likei + --i, and without the spaces this would cause problems. However, even when you’re just incrementing your loop variable, if you use the normal settings on JSLint, it will throw an error for usingi++. JavaScript Lint is a bit more sensible about this in that the increment operator is valid so long as you’re not combining it with other operators.October 17th, 2008 at 6:15
Interesting, as I’ve always tended to find curly braces on the new line more readable (maybe it’s just me). It’s something instilled in programming 101 classes. But with JavaScript I’ll have to curb that practice, I guess.
Thanks.
October 17th, 2008 at 9:16
Steven,
It’s actually quite an interesting debate on placement of curly braces.
On one hand, it does seem to improve readability for nested statements, but on the other hand it also increases the amount of “blank” lines in your code. This secondary effect means that you will be able to see less of your code on the screen at any given moment, which means a whole lot more scrolling.
I know that Microsoft advocates “opening brace on new line” for C#, which might give the impression that it is common or even considered good practice. I am sure that there are other vendors that also advocate this practice, so for once I am not bashing MS
But, once you get comfortable with a language, you should be able to read indented statements easily, regardless of placement of braces, and the value of using newlines for opening braces is greatly diminished. For JavaScript it can be fatal, and I expect that other languages like ActionScript would suffer the same fate.
It is my experience that you get the better code quality by assuming some level of skill by the reader, rather than writing code that is readable to newcomers of the particular language… they’ll get the hang of it soon anyway.
October 17th, 2008 at 9:26
Morgan,
Yeah, with proper options specified, I think I can support that initiative then.
Andrew,
Yes, I know about it, but at the end, it’s just about what options to specify. Meaning, I use the increment approach and JSLint, and we get along fine.
Thanks for the tip, though!
Steven,
Well, you don’t have to, if you’re careful. But personally, I’d just recommend it.
February 26th, 2009 at 1:46
[...] Others have pointed out this problem, such as in the JavaScript Style – why it’s important and Beware Of JavaScript Semicolon Insertion articles, both of which give similar examples. Another example of the problematic nature of [...]
March 7th, 2009 at 15:03
[...] Esiste anche un altro problema molto più subdolo generato dal “semicolo insertion”, ma per la cui analisi vi rimando a questo articoletto. [...]
July 25th, 2009 at 16:35
[...] Beware of JavaScript semicolon insertion – Robert’s talk [...]
Write a comment
Twitter reactions