6

There are lots of questions about "should I use semicolons?" and "how does semicolon injection work?", but I wanted to find FUD-free advice for a coder who has decided he want to avoid using semicolons as much as possible.

If someone has, like izs or the Bootstrap devs, chosen to write Javascript without semicolons, under what conditions must they add a semicolon, and what else should they do to ensure their code will not fail?

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
joeytwiddle
  • 29,306
  • 13
  • 121
  • 110
  • 2
    Just out of curiosity, what do you gain by not using them? – Matt R Aug 01 '14 at 21:26
  • @MattR I just popped open the Bootstrap source code and noticed how clean it looks. The semicolons I see everywhere else are something of a visual distraction, albeit minor. – joeytwiddle Aug 01 '14 at 21:32
  • 3
    I have the feeling the bootstrap devs omit semicolons to make their code appear "smart" and because [they just like it this way](http://www.wordsbyf.at/2011/10/31/i-dont-write-javascript/) (I can't find any reasonable argument in that article). Let's quote Douglas Crockfords opinion about this practice in bootstrap: [_"That is insanely stupid code."_](https://github.com/twbs/bootstrap/issues/3057) – kapex Aug 10 '14 at 10:18
  • 1
    Hi! I came from the future. Just wanted to add that the lack of semicolons on bootstrap have caused some consequences: https://github.com/twbs/bootstrap/issues/3057 ... Lots of them. https://github.com/twbs/bootstrap/issues/4699 https://github.com/twbs/bootstrap/issues/1905. These problems are just some ones I could find quickly. – Malavos Aug 24 '15 at 19:26
  • Despite coming from the future, one of your links was already shared by the previous commenter. Both of these issues were bugs with minifiers that were fixed, thanks to Bootstrap in at least one case. Happy [2016](https://github.com/atom/electron/pull/4909)! – joeytwiddle Apr 04 '16 at 16:44

1 Answers1

11

Avoid accidentally merging two lines

Assuming you intend to use a newline in place of semicolons, a commonly overlooked mistake is code that combines two lines into a single expression.

For example, the following code:

  // DANGEROUS
  a = b + c
  (d + e).print()

will be interpreted as:

  a = b + c(d + e).print()

The solution is:

  // SAFE
  a = b + c
  ;(d + e).print()

A similar concern arises with:

  // DANGEROUS
  console.log()
  ['three', 'two', 'one'].forEach(console.log)

So in general, the recommended rule to follow is:

When a line starts with a parenthesis ( or [

or with an arithmetic operator + - * / or regexp /.../

then put a semicolon ; in front of it.

(Note however that ++ -- and // are safe without a semicolon.)

(You would never actually write * or / alone, so it wouldn't make sense to start a line that way, but you might sometimes want to start a line with a /.../ regexp. In that case, if a semicolon is not used, this will most likely cause a syntax parsing error. The ( [ + - cases are more dangerous, because they would cause a runtime bug.)

Sources:

Avoid merging concatenated files, at start and end

For similar reasons, semicolons are also advisable at the start and end of a library script which will be released into the wild. In fact this is recommended regardless of what style you use in your script.

In this example with an IIFE:

  // my-library.js
  ;(function(){
      ...
  })();
  • The leading semicolon will ensure that your outer parentheses (...) will not try to invoke an un-terminated expression at the tail end of the script which has been concatenated before yours.

  • The trailing semicolon is good practice in case the script concatenated after yours starts with an IIFE and neglected to lead with its own semicolon.

As an alternative, Bootstrap leads with a +, does not wrap the IIFE in (...), and ends with a ;. Other variations lead with ! instead of + or ;.

Places where semicolons are normal

The only other time semicolons are required are in traditional for loops:

  for (var i = 0; i < 10; i++) { // good luck doing that without semicolons!

and when you are otherwise placing multiple statements on one line:

  x = obj[k]; delete obj[k]; return asChar(x)

Use a linter

Some linters will detect when your code may have unintended consequences, and encourage you to follow the practices above.

For example, the so-called standardjs linter will detect the concerns raised above. (They also have released an eslint config if you prefer to use eslint, but I'm not sure how comprehensive those rules are.)

joeytwiddle
  • 29,306
  • 13
  • 121
  • 110
  • 2
    In `'use strict';`, you need semicolon there. – elclanrs Aug 01 '14 at 21:19
  • 1
    Although it is written in the spec that `'use strict'` should be followed by a semicolon, in practice [it works](https://github.com/twbs/bootstrap/issues/1905) [fine](https://github.com/electron/electron/blob/master/lib/browser/init.js) without a semicolon, provided you follow the rules mentioned above. – joeytwiddle Apr 02 '17 at 06:03