Beware of JavaScript semicolon insertion

Published on Thursday, October 16th, 2008

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.

13 comments

  • Remy Sharp
    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

  • Morgan Roderick
    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.

  • Morgan Roderick
    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

  • icaaq
    October 16th, 2008 at 19:38

    That and other things is noticed when you slap your code into lint http://jslint.com/

  • Robert Nyman - author
    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!

  • Jonathan Snook
    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.

  • Morgan Roderick
    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.

  • Robert Nyman - author
    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.

  • Morgan Roderick
    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 :)

  • Andrew Noyes
    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 for loop declarations, JSLint will throw an error for using the increment operator. Crockford has a valid reason for this: it’s hard to read code like i + --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 using i++. 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.

  • Steven Clark
    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.

  • Morgan Roderick
    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.

  • Robert Nyman - author
    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.

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview

Top results