-3

When executing a function in JavaScript, I've always ended my code block with a semi-colon by default, because that's what I've been taught to do. Coming from Java it felt a bit unorthodox at first, but syntax is syntax.

function semiColon(args) {
   // code block here
};

or

function sloppyFunction(args) {
   // code block here
}

Lately I've been seeing more and more code where the developer left the semi-colon out after functions, but the intended code still executed normally. So are they actually required? If not, why is it common practice to include them? Do they serve another purpose?

  • 1
    I think it's pretty rare to put semicolons after function *declarations*, because they're treated like block expressions. (I'm not sure if that's what they formally are in the syntax, but that's how people treat them.) However, you should probably always use semicolons after regular statements (**exactly as you would in Java, really**) to avoid a few edge cases in the automatic semicolon insertion (which isn't really meant to be relied on). – Jeremy Mar 18 '16 at 18:26

3 Answers3

1

Function declarations do not need a semi-colon, though if you put a semi-colon there, it won't be harmful, it is just a redundant empty statement.

function semiColon(args) {
   // code block here
};;;; // 4 empty statements

Most statements require a semi-colon, but if you leave the semi-colon out it will be inserted automatically in most cases by Automatic Semi-Colon Insertion, with caveats. In general it is easier to just always add a semi-colon after your statements, so that you, and other developers working with your code, don't have to worry about those caveats.

This code is correct:

function semiColon(args) {
   // code block here
} // No need for semi-colon

var semiColon = function (args) {
   // code block here
}; // Semi-colon required here

Whereas this code is wrong, but will still usually work:

function semiColon(args) {
   // code block here
}; // Redundant unnecessary Empty Statement 

var semiColon = function (args) {
   // code block here
} // Semi-colon required here,
// but ASI will sometimes insert it for you, depending on
// the subsequent token
Community
  • 1
  • 1
Paul
  • 130,653
  • 24
  • 259
  • 248
  • Strictly speaking function declarations are not statements, but it almost doesn't make any practical difference these days. – Felix Kling Mar 18 '16 at 18:31
1

NO - using semicolons to end function declarations are NOT necessary in JavaScript. While they will not throw an error, they are the equivalent of using more than one semicolon to end a line of code - harmless, but unnecessary. Being superfluous, they are considered poor stylistic and programming practice.

The one exception is a function expression, e.g.

var my_function = function(a, b){ };

where you DO need the semicolon to terminate the line.

Sensei James
  • 2,345
  • 25
  • 33
0

You shall not add a semicolon after a function declaration.

Because, after checking the Javascript grammar:

  • StatementList:

    • StatementListItem
    • StatementList
  • StatementListItem:

    • Statement
    • Declaration
  • Declaration:

    • HoistableDeclaration
    • ClassDeclaration
    • LexicalDeclaration
  • HoistableDeclaration:

    • FunctionDeclaration
    • GeneratorDeclaration

Here's the grammar production for a function:

FunctionDeclaration → HoistableDeclaration → Declaration → StatementListItem → StatementList

which proves that my former response is wrong (no need to look at the former edits, as it's wrong! ;) ).

A function xx() {} construct alone is a special case, neither — strictly speaking — a statement or an expression, and thus is NOT to be ended with a semicolon.

You only need to add a semicolon (or leave the ASI take care of it) if you're using the expression function() construct, which exists when it is part of a statement. To make it a statement you need to either have it part of a statement:

var foo = function() {};

or embedded within another expression:

(function() {})();
!function x() { ... }();

And in either cases, you need to add the semicolon at the end of the full statement, obviously.

Generally speaking, I like the python mantra "explicit is better than implicit" so when you hesitate to add a semicolon that the ASI would add otherwise, just add it.

sorry for being wrong in the first version of my answer, I'll debug some PHP code as a penitence. ☺

HTH

zmo
  • 22,917
  • 4
  • 48
  • 82
  • 1
    *"ASI will add a semicolon here anyway"* No it won't. ASI only takes place if the code could not be parsed otherwise (and some additional rules). But there is also this very specific rule: *"However, there is an additional overriding condition on the preceding rules: a semicolon is never inserted automatically if the semicolon would then be parsed as an empty statement "*. So, even if ASI always took place, it wouldn't insert a semicolon after the declaration, because that would be an empty statement. – Felix Kling Mar 18 '16 at 18:34
  • ok, I agree with what you say, even though you're wrong about one thing: `function x() { ... }` is an _expression_, NOT a _statement_. So a trailing `;` will make the expression into a statement, and not add an empty statement. – zmo Mar 18 '16 at 18:41
  • Not sure I understand your edit. `function x() { return true; }.name` is a syntax error. `function x() { ... }` is a function declaration, not an expression. – Felix Kling Mar 18 '16 at 18:41
  • @zmo `function x() { ... }` on its own is not an expression, it's a function declaration. Hence why `function x() { ... }()` doesn't work and people use tricks like `(function x() { ... })()` and `!function x() { ... }()` to convert the function into an expression – Paul Mar 18 '16 at 18:42
  • weird, actually I've based my comments, on testing within the nodejs console, but it's not working with V8 or Spidermonkey. – zmo Mar 18 '16 at 18:45
  • The Node REPL is likely doing something funky with the input. – Felix Kling Mar 18 '16 at 18:48
  • ok, after checking the javascript grammar, I'm amending my answer, sorry for the trouble. – zmo Mar 18 '16 at 18:57