The dangers of JavaScript ' s Automatic semicolon insertion

Source: Internet
Author: User

Although JavaScript is very powerful, the language ' s fundamentals does not have a very steep learning curve.  Prior to the explosion of Web applications, JavaScript is thought of a toy language for amateur programmers.  Some of JavaScript ' s features were specifically designed to cater.  One such feature is automatic semicolon insertion. Automatic semicolon insertion is also one of the JavaScript ' s most controversial features.

JavaScript ' s syntax borrows heavily from C and Java.  programmers that is familiar with these languages is Accus Tomed to semicolon terminated statements.  javascript statements is also terminated by semicolons, but unlike C and Java, these semicolons is not always requ Ired.  in an effort to "help" programmers, the JavaScript interpreter'll actually insert Om Itted semicolons where it deems necessary.  unfortunately, automatic semicolon insertion, which is intended to act as a crutch for programmers, can actually in Troduce difficult to find bugs.  in my opinion, it also promotes bad programming practices by don't forcing developers to properly terminate statements .

Section 7.9.1 of the ECMAScript 5.1 standard specifies rules governing automatic semicolon insertion.  to und Erstand the rules, you should first understand the concept of tokens.  most of the rules involve inserting a semicolon at the end of a line of code― referred to as a LineTerminator Token.  because automatic semicolon insertion rules is related to line breaks, whitespace CA n effect the execution of JavaScript programs.  many Common languages (C, Java, HTML) allow developers to ignore whitespace.  developers who is familiar with these languages can run into problems in JavaScript due to this assumption.

It is important to recognize the scenarios where automatic semicolon insertion are applied.  There is also a number of scenarios where semicolons is not automatically inserted. The following sections describe the rules for inserting (or not inserting) semicolons automatically.

LineTerminator, Closing braces, and End of Stream

The JavaScript interpreter would insert a semicolon between the statements when they is separated by a lineterminator or a  } token.  A semicolon'll also is inserted, if needed, at the end of the input stream. The following ' If ' statement is, surprisingly, valid JavaScript.

if (i = = 0)  {=  1 = 2} baz = 3

A semicolon is inserted between, the ' foo ' and ' bar ' assignment statements because they are separated by a lineterminator.  Another semicolon is inserted after the ' bar ' assignment because the next token is a closing curly brace.  A final semicolon is inserted after the ' Baz ' assignment because the end of the input stream has been reached. After semicolon insertion, the ' if ' statement looks like this:

Return, throw, continue, and break statements

If A LineTerminator token is encountered immediately after a ' return ', ' throw ', ' continue ', or ' break ' token, a semicolon  is automatically inserted. This means, labels in ' Continue ' and ' break ' statements must is specified on the same line as the respective ' cont  Inue ' or ' break ' token.  Similarly, expressions in ' return ' and ' throw ' statements must begin on the same line as the ' return ' or ' throw ' token. For example, the following ' return ' statement does not exhibit the behavior, the developer likely intended.

return+ b;

The developer most likely intended to return the result of the expression ' A + B '.  However, when this ' return ' statement was parsed by the interpreter, it was transformed to look like the following code. In this case, the return value is undefined and the ' A + B ' expression becomes unreachable code.

return+ b;

' Return ' statements that return object literals is potentially the most common victims of semicolon insertion related bug  S. Object literal syntax lends itself well to being split across multiple lines.  This is especially true for large objects. For example, the following function returns a undefined value.

function GetObject () {  return  {    1    //  many more fields  };}
Postfix Operators

The postfix operators ' + ' and ' – ' must appear on the same line as their operand.  If A lineterminator occurs between the operand and the operator, then a semicolon would be inserted by the interpreter.  These mistakes is uncommon. For example, a developer was unlikely to the write ' i++ ' on multiple lines.

For statements

The header of a ' for ' loop must always contain-semicolons.  according to the specification, semicolons is Nev Er automatically inserted into the header of a ' for ' loop.  this means the programmer is responsible for including both semicolons.  for example, the following loops is valid JavaScript:

 for (var i = 0; i < 5; i++) {  //  loop body} for (;;) {  //  loop body}  for (var i = 0; i < 5; I+ +)  {//  loop Body}

However, the following loops was not valid because the missing second semicolon was not automatically inserted.

 for (var i = 0; i < 5i+ +)  {//  loop body} for (;) {  //  loop Body}
Empty statements

Semicolons is also never inserted when the resulting statement would is the empty statement―a statement that consists O  F only a semicolon.  The following ' If-else ' statement is invalid. The interpreter won't insert a semicolon in the ' if ' clause because the resulting statement would is empty.

if (i = =5  ) // no semicolon 'll be inserted here Else    = 0;
A more complicated Example

All semicolons has been removed from the following example.  In this case, it can is more difficult to determine the semantics of the code. What is the value of ' Foo ' being at the end of the example?

 var   foo  var   bar  var  baz =  return  data + 1}bar  = 1< Span style= "color: #000000;" >foo  = bar + Baz (bar  + bar) + Baz (bar) 

Let ' s analyze the code.  The first three lines declare the variables ' foo ', ' Bar ', and ' Baz '.  ' Baz ' is a function, that increments it ' data ' argument by one.  Because the expression ' data + 1′begins on the same line as the ' return ' token, ' Baz ' returns the expected value.  The ' Bar ' assignment statement is straightforward.  The ' foo ' assignment is trickier. A semicolon isn't inserted between the last of the lines because the opening parentheses indicates a function call that Bega  N on the previous line. Therefore, the ' foo ' assignment actually looks like this:

Foo = bar + baz (bar + bar) + baz (bar);

Now it's fairly simple to compute ' foo '. The final value of ' Foo ' is six.

Things to Remember
    • If the programmer leaves out a semicolon, the JavaScript interpreter would insert it automatically in some circumstances.

    • Automatic semicolon insertion can introduce bugs which is difficult to locate because whitespace changes semantics.

    • Programmers should never rely on automatic semicolon insertion.

Appendix

The following excerpt is taken directly from sections 7.9.1 of the standard, which describes the rules for automatic Semico  Lon insertion. The ' Restricted Productions ' mentioned in Rule #3 relate to postfix operators and the ' continue ', ' break ', ' return ', and ' Throw ' statements.

Begin Excerpt

There is three basic rules of semicolon insertion:

  1. When, as the program was parsed from left to right, a token (called the offending token) is encountered that's not allowed By any production of the grammar, then a semicolon is automatically inserted before the offending tokens if one or more The following conditions is true:

      • The offending token is separated from the previous tokens by at least one lineterminator.

      • The offending token is}.

  2. When, as the program was parsed from left to right, the end of the input stream of tokens are encountered and the parser is Unable to parse the input token stream as a ECMAScript program, then a semicolon is automatically inserted At the end of the input stream.

  3. When, as the program was parsed from left to right, a token was encountered that was allowed by some production of the Gramma R, but the production is a restricted production and the token would being the first token for a terminal or nonterminal imme diately following the Annotation―[no LineTerminator Here]‖within the restricted production (and therefore such a token I s called a restricted token), and the restricted token is separated from the previous tokens by at least one LineTerminator , then a semicolon is automatically inserted before the restricted token.

However, there is a additional overriding condition on the preceding rules:a semicolon is never inserted automatically I f The semicolon would then is parsed as an empty statement or if that semicolon would become one of the the one and the other semicolons in The header of a For statement (see 12.6.3).

End Excerpt

So in JavaScript, many project managers are demanding

function Test () {    console.log (' test ');}

Rather than like this format:

function Test () {    console.log (' test ');  }

is to minimize the occurrence of this problem.

The dangers of JavaScript ' s Automatic semicolon insertion

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.