Introduction

In JavaScript, it is said that semicolons are optional. It's true, because JavaScript automatically inserts a semicolon, where it is required. Sometimes this feature confuses us a lot. This article is written for those who have just started writing JavaScript and for those who don’t know the automatic insertion of semicolon in JavaScript.
  1. function fun1() {
  2. return {
  3. a: 10
  4. };
  5. }
  6. function fun2() {
  7. return {
  8. a: 10
  9. };
  10. }
At first look, the code given above looks the same but look at the output given below.
Console.log(fun1());
Output
Object { a: 10 }
Console.log(fun2());
Output

undefined

It is surprising that fun2() returns undefined without any error being thrown.
The reason behind the function returning undefined is the fact that in JavaScript semicolons are optional (although it is not a good practice to ignore them). Hence, when the line with the return statement is executed in fun2(), it automatically places a semicolon immediately at the end of the return statement. In this case, no error is thrown as the remainder is perfectly valid, even though it is not invoked and doesn't do anything.
This behavior also suggests following the convention of placing an opening curly brace at the end of the same line and not at the new line.
Following statements must be terminated with the semicolons

Rules of automatic semicolon insertion

There are three basic rules of semicolon insertion, which are given below.
Note, the token ++ is not treated as a postfix operator applying to the variable b, because a LineTerminator occurs between b and ++.
  • In this case, a semicolon will be inserted, if the token is allowed by some production of the grammar, but it is restricted production.
    1. UpdateExpression: LeftHandSideExpression[no LineTerminator here]++
    2. LeftHandSideExpression[no LineTerminator here]--
    3. ContinueStatement: continue;
    4. continue [no LineTerminator here] LabelIdentifier;
    5. BreakStatement: break;
    6. break [no LineTerminator here] LabelIdentifier;
    7. ReturnStatement: return;
    8. return [no LineTerminator here] Expression;
    9. ThrowStatement: throw [no LineTerminator here] Expression;
    10. ArrowFunction: ArrowParameters[no LineTerminator here] => ConciseBody
    11. YieldExpression: yield [no LineTerminator here] * AssignmentExpression
    12. yield [no LineTerminator here] AssignmentExpression
The example, which we have seen at the start of the article is the best for understanding ReturnStatement (restricted production).