67

Many times I've seen a semicolon used after a function declaration, or after the anonymous "return" function of a Module Pattern script. When is it appropriate to use a semicolon after curly braces?

double-beep
  • 5,031
  • 17
  • 33
  • 41
Rob Gibbons
  • 1,583
  • 3
  • 14
  • 24

8 Answers8

109

You use a semicolon after a statement. This is a statement:

var foo = function() {
  alert("bar");
};

because it is a variable assignment (i.e. creating and assigning an anonymous function to a variable).

The two things that spring to mind that aren't statements are function declarations:

function foo() {
  alert("bar");
}

and blocks:

{
  alert("foo");
}

Note: that same block construct without semi-colon also applies to for, do and while loops.

double-beep
  • 5,031
  • 17
  • 33
  • 41
cletus
  • 616,129
  • 168
  • 910
  • 942
25

It matters too when you intend to minify your code.

So I personally add one after every } where automatic semicolon insertion (ASI) would insert one.

I wrote a post about ASI in JavaScript.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
alex
  • 479,566
  • 201
  • 878
  • 984
20

Don't use a semicolon:

...if it's just your every-day function declaration:

function foo() {

} // No semicolon


Use a semicolon:

...if it's an assignment:

var foo = function() {

}; // Semicolon


...or a self invoking function:

(function () {

})(); // Semicolon
Web_Designer
  • 72,308
  • 93
  • 206
  • 262
10

You never need to; you always can (except before else and while).

Explanation:

Unfortunately, JavaScript semicolons are optional.
Therefore, you never need to add a semicolon.

It is (very) good practice to terminate every statement with a semicolon.
The only statements that end with a } are statements ending with an object literal (e.g. JSON) or function expression.

Therefore, best practice is to put semicolons after the following two braces (only):

var myFunc = function() { };
var myobject = { };
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Is using `function someFunc(){ };` is still a statement that needs semicolon? – ilyo May 26 '11 at 11:27
  • 1
    You "need" to if you want your minified Javascript to work in IE, which is the only browser I've found that chokes without them. Firefox/Chrome/Safari don't care about semicolons after statements. – Cerin Nov 07 '12 at 17:17
  • @Cerin: I don't think that's true. – SLaks Nov 08 '12 at 17:15
  • @SLaks, Try it yourself. Minify JS without semicolons and try running it in IE9. I just wasted several hours of my life figuring this out. Thought I'd share to others the hassle. – Cerin Nov 08 '12 at 20:55
  • @Cerin: I tried it worked in IE9. Could you share the minified sample you are using to test? – monish001 Oct 10 '13 at 16:05
5

If we have a self-invoking function, we need to put a semicolon before it, otherwise it becomes part of the previous assignment statement. Consider the following:

testClass = function(name) {
  document.write ("Instantiating testClass<br />");
  this.name = name;
}

testClass.prototype.report = function() {
  document.write ("I'm " + this.name + "<br />");
  return 1;
}

testClass.prototype.testMethod = function(param) {
  document.write ("Running testMethod with parameter value " + param + "<br />");
  return 2;
} // notice that there is no semicolon here

(function() {
  document.write ("Running self-invoking function<br />");
  return 3;
}());

if (typeof(testClass.prototype.testMethod) !== "function") {
  document.write ("testMethod type: " + typeof(testClass.prototype.testMethod));
  document.write (", value: " + testClass.prototype.testMethod + "<br />");
}
var testOb = new testClass("Bill");
testOb.report();
testOb.testMethod(4);


This will produce the following output:

"Running self-invoking function
Running testMethod with parameter value 3
testMethod type: number, value: 2
Instantiating testClass
I'm Bill"

...plus a JavaScript error reported by the browser: testOb.testMethod is not a function

This is certainly not what we intended. Why is testMethod running immediately, before we have even instantiated the class? And why does it no longer exist when we want to call it as a member method?

What is happening is that testMethod is being assigned not our function definition, but the return value of the function definition. And the function definition itself is being run anonymously. This is how:

  1. The testClass constructor and the member method report are successfully defined/assigned.
  2. Because of the lack of a semicolon after the definition for testMethod, the () surrounding the following self-invoking function becomes an invocation operator, which causes what we think is our definition of testMethod to become an anonymous function that is invoked immediately, and the return value of the following anonymous function becomes its parameter list. This explains the order of printed output - our self-invoking function is run first as it is evaluated as a parameter.
  3. Since our intended function definition returns 2, it is this 2 that is assigned to testMethod, and not the function definition. This is confirmed by our printing of the type and value of testMethod.
  4. Now testClass is successfully instantiated as testOb and its report method works as intended, proving that the class definition is otherwise intact.
  5. When we try to call testMethod, we are told by the interpreter that it is not a function - and rightly so, because it is a number with the value 2.

If we put a semicolon after the definition of testMethod, it will separate its assignment from the calling of the self-invoking function, and we will have the result we expected:

"Running self-invoking function
Instantiating testClass
I'm Bill
Running testMethod with parameter value 4"



Or we could even put it directly before the anonymous function:

;(function() {...

But I suggest that since the problem is due to the lack of a semicolon at the end of an assignment statement, we should perhaps make a habit of always putting a semicolon after defining functions in this way. i.e. all of my functions above should have a semicolon after the closing brace, because they are all assignments of anonymous functions.

mipe34
  • 5,596
  • 3
  • 26
  • 38
Code83
  • 148
  • 2
  • 7
2

You also should use a semicolon after a curly bracket after returning a function within a function in JavaScript.

function watchOut(problem) {
  return function(number, location) {
    alert("Be careful! There are " + problem +
          " today!\n" +

          number + " have been spotted at the " + location + "!"
    );
  };
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MarcNC
  • 31
  • 2
0

Consider this code:

// This will break code

a=b=c=d=e=1
a = b + c     // Semicolon required here
(d + e).toString()

It will return "Property of object [object Object] is not a function". Because it will actually be executed as:

a = b + c(d + e).toString()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kush
  • 755
  • 7
  • 22
-1

Semicolons go at the end of lines that do not end in a curly brace or to separate statements on the same line. It does no harm to use them after a closing brace, or to wear suspenders and a belt, but it does look a little nerdy.