From 8cf2c70a4164ba2dad9a79e7ac9021d32a406487 Mon Sep 17 00:00:00 2001 From: Josh Bourgeois Date: Wed, 4 Oct 2017 13:38:13 -0700 Subject: [PATCH] [guide] Add explanation for semicolon enforcement rule Also update code samples to highlight ways in which ES6 currently mishandles code when relying on Automatic Semicolon Insertion Revise hyperlink and example - Use more up-to-date TC39 reference page on github.io - wrap returnless function with side-effects in curly braces also, clean up punctuation on a long comment line Always use single-quoted strings Except for when the string needs to be double-quoted because the string contains apostrophes Update second example to incorporate IIFE An IIFE is a more realistic example of code that developers may encounter which would raise an exception when relying completely upon ASI --- README.md | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 52b5ed4a..05d62578 100644 --- a/README.md +++ b/README.md @@ -2767,24 +2767,45 @@ Other Style Guides - [21.1](#semicolons--required) **Yup.** eslint: [`semi`](https://eslint.org/docs/rules/semi.html) jscs: [`requireSemicolons`](http://jscs.info/rule/requireSemicolons) + > Why? When JavaScript encounters a line break without a semicolon, it uses a set of rules called [Automatic Semicolon Insertion](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion) to determine whether or not it should regard that line break as the end of a statement, and (as the name implies) place a semicolon into your code before the line break if it thinks so. ASI contains a few eccentric behaviors, though, and your code will break if JavaScript misinterprets your line break. These rules will become more complicated as new features become a part of JavaScript. Explicitly terminating your statements and configuring your linter to catch missing semicolons will help prevent you from encountering issues. + ```javascript - // bad - (function () { - const name = 'Skywalker' - return name - })() + // bad - raises exception + const luke = {} + const leia = {} + [luke, leia].forEach(jedi => jedi.father = 'vader') + + // bad - raises exception + const reaction = "No! That's impossible!" + (async function meanwhileOnTheFalcon(){ + // handle `leia`, `lando`, `chewie`, `r2`, `c3p0` + // ... + }()) + + // bad - returns `undefined` instead of the value on the next line - always happens when `return` is on a line by itself because of ASI! + function foo() { + return + 'search your feelings, you know it to be foo' + } // good - (function () { - const name = 'Skywalker'; - return name; + const luke = {}; + const leia = {}; + [luke, leia].forEach((jedi) => { + jedi.father = 'vader'; + }); + + // good + const reaction = "No! That's impossible!"; + (async function meanwhileOnTheFalcon(){ + // handle `leia`, `lando`, `chewie`, `r2`, `c3p0` + // ... }()); - // good, but legacy (guards against the function becoming an argument when two files with IIFEs are concatenated) - ;((() => { - const name = 'Skywalker'; - return name; - })()); + // good + function foo() { + return 'search your feelings, you know it to be foo'; + } ``` [Read more](https://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function/7365214#7365214).