JS magic Hall: ASI (automatic semicolon insertion mechanism) and Front semicolon
I. Preface I will see the frontend Technical Expert of the People's Network in zhihu tonight-He Shijun-should I add points to JavaScript statements? The answer, let me once again see the elegant style of Daniel, really admire. However, the Pure admiration is not enough to return to such excellent texts. It is worthy of understanding the meaning of the texts and the principles behind them! Before that, we need to understand ASI (automatic semicolon insertion mechanism ). Ii. Automatic Semicolon Insertion (ASI, Automatic Semicolon Insertion mechanism) main reference: http://justjavac.com/javascript/2013/04/22/automatic-semicolon-insertion-in-javascript.html engaged in C # and Java monkeys know that Semicolon is used as a sentence (EOS, end of statement, additionally, you must add extra points. Otherwise, the compilation will fail. However, JavaScript allows us to omit semicolons because of the ASI mechanism. The ASI mechanism does not mean that the parser automatically adds semicolons to the Code during the parsing process, but that apart from semicolons, the parser also uses some rules as the basis for sentence breaking, this ensures the correctness of the resolution. First, these rules are based on two points: 1. for the basis of behavior; 2. the parser tries its best to merge the new row into the current row. The new row is considered as an independent statement only when it complies with the ASI rule. ASI Rules 1. the new row is merged into the current row to form an invalid statement. if (1 <10) a = 1console is inserted automatically. log (a) // equivalent to if (1 <10) a = 1; console. log (a); 2. insert the semicolon return {a: 1} // equivalent to return; {a: 1}; 3. ++, -- suffix expression is used as the start of a new line. The semicolon a ++ c is automatically inserted at the beginning of the line. // It is equivalent to a; ++ c; 4. the last statement of the code block will automatically insert a semicolon function () {a = 1} // equivalent to function () {a = 1;} No ASI Rule 1. the new line starts with var a = 1var B = a (a + B ). toString () // It will be parsed to call function a with a + B as the input parameter, and then call the toString function var a = 1var B returned by the function. = A (a + B ). toString () 2. the new line starts with [var a = ['a1', 'a2 '] var B = a [0, 1]. slice (1) // will be parsed first to obtain a [1], and then call a [1]. slice (1 ). // Because the comma is located in [] and is not parsed as an array literal, It is parsed as an operator. The comma operator executes the expression on the left first, then execute the expression on the right and use the calculation result of the expression on the right as the return value var a = ['a1', 'a2 '] var B = a [0, 1]. slice (1) 3. the new line starts with/var a = 1var B = a/test /. test (B) // is parsed as the Division operator, rather than the starting symbol of the regular expression literal. In the browser, an additional test is reported. var a = 1var B = a/test /. test (B) 4. the new row starts with +,-, %, and *. var a = 2var B = a + a // the following format is parsed: var a = 2var B = a + a 5. new Line with, or. start var a = 2var B =. toString () console. log (typeof B) // It is parsed as var a = 2var B =. toString () console. log (typeof B) Here we have a certain understanding of the ASI rules, and there is also an interesting thing, that is, the "null statement ". // Three empty statements; // only the if condition statement is available. The statement block is an empty statement. // The unless condition statement can be implemented if (1> 2); else console. log ('2 is greater than 1 always! '); // Only the while condition statement. The loop body is a null statement. Var a = 1 while (++ a <100); 3. prefix the semicolon to reiterate the role of the semicolon-as the statement's asserted (EOS), so that the parser can correctly parse the program. Now that there is an ASI mechanism, why do there are still many code specifications that require the write of semicolons? There are three other reasons: 1. There is No ASI, so you are too lazy to remember these special cases; 2. Team engineers need to consider both front-end and back-end development (such as me ~~), The backend adopts Java, C #, or PHP to keep the code specifications at both ends close to the low management cost. 3. This is the case with the old specifications, and there is no need to change them now. After the semicolon is omitted, the Code compression tool will have problems. jslint will report problems such as warning to the code without the semicolon. He Shijun has explained it in detail in his reply. Therefore, the separation of semicolons is purely a matter of personal and team preferences. Of course, you can also use them in a mix (refer to the figure of Daniel @ plateau below). If you do not need to tap on the keyboard, you can tap less, A big lazy who can use it without a mouse will naturally join the "No semicolon party". The prerequisite for joining the party is to remember the rules to deal with the No ASI situation: the number of extra points before a statement starting with ([/+-) (because it is normal ., * % is the beginning of the statement. Therefore, you only need to remember the first five items. If you are too lazy, you will be lazy) then we can make the code structure clearer through reasonable indentation and blank lines (isn't coffeescript like this ?!) Example:; (function (exports, undefined) {var getKeys = Object. getOwnPropertyName & Object. getOwnPropertyName. bind (Object) | function (obj) {var keys = [] for (var key in obj) keys. push (key) return keys} var each = exports. forEach = exports. each = function (arrayLike, fn, ctx) {if (arrayLike = undefined) return var isObj = arrayLike. length! ==+ ArrayLike. length, keys = isObj? GetKeys (arrayLike): arrayLike, len = keys. length, idx for (var I = 0; idx = isObj? Keys [I]: I, I <len; ++ I) fn. call (ctx, idx, arrayLike [idx])} (new Function ('Return this ') (), void 0) forEach ({'s': 1, 'C': 2}, function (I, item) {console. log (I + ''+ item)}) forEach ([1, 2], function (I, item) {console. log (I + ''+ item)}) Now we can make a" No semicolon party "with peace of mind!