2

Specifically in JavaScript, when does one use a semicolon and when do you not.

Here is an example snippet of code;

function Drawable() {
   this.init = function(x, y) {
      this.x = x;
      this.y = y;
   }

   this.speed = 0;
   this.canvasWidth = 0;
   this.canvasHeight = 0;

   this.draw = function() {
   };
}

Can someone enlighten me as to why

this.init = function(x,y) {}

does not end with a semicolon, however

this.draw = function(){};

does end with a semicolon in the above snippet of code?

Dan K
  • 409
  • 3
  • 12
  • [relevant](http://benalman.com/news/2013/01/advice-javascript-semicolon-haters/). – zzzzBov Jun 26 '13 at 18:35
  • 1
    Actually, I'd say the answer is that you're very observant; my nitpickiness when coding would have added the semicolon to the first one as well. That said, I can see why it wouldn't occur to someone to include it (and all JS parsers I know of would easily handle that automatically) – Katana314 Jun 26 '13 at 18:37
  • 1
    It's because whoever wrote that code isn't consistent. –  Jun 26 '13 at 18:38
  • If the next character after any whitespace following `}` of `this.init` starts with a `(`, `this.init` will be the result of the invocation of the anonymous function. – Paul S. Jun 26 '13 at 18:48

2 Answers2

8

This a matter of personal style since JavaScript sports automatic semicolon insertion.:

When, as the program is parsed from left to right, a token (called the offending token) is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token if... The offending token is separated from the previous token by at least one LineTerminator.

The first one does not end in a semicolon because the above code is inconsistent.

The consistent way would have been:

this.init = function(x, y) {
   this.x = x;
   this.y = y;
};

The issue of whether or not you should use them has been discussed in SO before.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
1

From Google JavaScript Style Guide:

// 1.
MyClass.prototype.myMethod = function() {
  return 42;
}  // No semicolon here.

(function() {
  // Some initialization code wrapped in a function to create a scope for locals.
})();


var x = {
  'i': 1,
  'j': 2
}  // No semicolon here.

// 2.  Trying to do one thing on Internet Explorer and another on Firefox.
// I know you'd never write code like this, but throw me a bone.
[normalVersion, ffVersion][isIE]();


var THINGS_TO_EAT = [apples, oysters, sprayOnCheese]  // No semicolon here.

// 3. conditional execution a la bash
-1 == resultOfOperation() || die();

1 - JavaScript error - first the function returning 42 is called with the second function as a parameter, then the number 42 is "called" resulting in an error.

2 - You will most likely get a 'no such property in undefined' error at runtime as it tries to call x[ffVersion]isIE.

3 - die is called unless resultOfOperation() is NaN and THINGS_TO_EAT gets assigned the result of die().

Community
  • 1
  • 1
fmsf
  • 36,317
  • 49
  • 147
  • 195
  • 1
    That's in the google code style guide under "There are a couple places where missing semicolons are particularly dangerous:" but your answer makes it sound like this is the expected style. – Benjamin Gruenbaum Jun 26 '13 at 18:39
  • @BenjaminGruenbaum his first example is not so uncommon I think (defining methods in a constructor function and having an IIFE as initialization method at the end). I also stumbled upon this and it took me quite a long time to find out where my error was. In a way it's still a question of style I guess but I also think people should be encouraged to not rely too much an ASI and just learn where to put semicolons. – basilikum Jun 26 '13 at 18:58
  • @basilikum Oh I completely agree, I always use semicolons and I always lint my code with JSHint. That's not what I was commenting about. I personally don't like ASI. – Benjamin Gruenbaum Jun 26 '13 at 19:05
  • @BenjaminGruenbaum Then I maybe misread your comment. Sorry for that. – basilikum Jun 26 '13 at 19:30