3

I always assumed that all whitespace (spaces, tabs, newlines) in JavaScript source code was 'equal', i.e. they're all valid to separate language elements such as identifiers, keywords, operators, etc.

However, I noticed a strange difference between newlines versus spaces or tabs. Even inside comments!

This works OK: (line break between function definition and function call, but no semicolon)

var bla = function() { alert('hello') }
bla();

This also works: (semicolon between the closing } character and the bla() function call)

var bla = function() { alert('hello') };bla();

However, this does NOT work: (no difference whether there's just one space or tab, or multiple, or none)

var bla = function() { alert('hello') } bla();

And it gets even stranger.

This doesn't work either: (separated by comment containing space, tab and semicolon)

var bla = function() { alert('hello') } /*  ; */ bla();

But this does: (comment containing line break)

var bla = function() { alert('hello') }/*
*/bla();

Live jsfiddle demos:

Is this a bug in JavaScript, or am I missing something?

Rogier
  • 153
  • 5
  • [Here's](http://coding.smashingmagazine.com/2011/05/30/10-oddities-and-secrets-about-javascript/) [some](http://www.slideshare.net/pigulla/javascript-wtfs-8148743) [more...](http://stackoverflow.com/questions/1995113/strangest-language-feature). If you write [good Javascript](http://javascript.crockford.com/), you'll endure much less pain. – beatgammit Oct 24 '13 at 09:23

1 Answers1

6

This is not down to white space misbehaving, it is down to Javascript's "ASI" feature: "Automatic Semicolon Insertion".

This is a feature that was included in the Javascript language when it was first introduced. Basically, the deal is this:

The core JS language requires every statement to be terminated with a semi-colon.

However, because the language was aimed at web designers (who at the time were not considered to be programmers), the parser was modified to be lenient if the developer forgot to include semi-colons. If the parser thinks a semi-colon is missing, but there is a line-break, it will make an assumption that a semi-colon was intended.

Frankly, this is a really really poor decision in the design of the language: it leads to a number of known quirks that can result in issues which can be very difficult to debug. In particular, you need to be very very careful about this around return statements that are returning multi-line object structure, but there are lots of other ways it can catch you out, as your question demonstrates.

The lesson to learn here is simple: always include the semi-colons between your JS statements, even where they appear to be optional.

You can read more about ASI here if you're really interested in the topic, and it is an important thing to be aware of as a Javascript programmer. But in general if you just include your semi-colons, you can mostly forget about it.

Spudley
  • 166,037
  • 39
  • 233
  • 307
  • The thing that's got me more than once is that 'return' on a line of its own ignores the expression on the line(s) following it (due to ASI). So I've started to use a pattern where I write return 0 , ... real return-value. So instead of adding extra parenthesis around the result-expression, I just add "0, " before it. I think that makes the code easier to read. – Panu Logic Jun 17 '20 at 20:56
  • If they are necessary after each line break, then why are they necessary at all? Aren't they redundant next to an actual line break? – Juan Perez Feb 23 '22 at 03:22