]> git.proxmox.com Git - pve-eslint.git/blob - eslint/docs/src/rules/semi.md
import 8.41.0 source
[pve-eslint.git] / eslint / docs / src / rules / semi.md
1 ---
2 title: semi
3 rule_type: layout
4 related_rules:
5 - no-extra-semi
6 - no-unexpected-multiline
7 - semi-spacing
8 further_reading:
9 - https://blog.izs.me/2010/12/an-open-letter-to-javascript-leaders-regarding/
10 - https://web.archive.org/web/20200420230322/http://inimino.org/~inimino/blog/javascript_semicolons
11 ---
12
13
14
15 JavaScript doesn't require semicolons at the end of each statement. In many cases, the JavaScript engine can determine that a semicolon should be in a certain spot and will automatically add it. This feature is known as **automatic semicolon insertion (ASI)** and is considered one of the more controversial features of JavaScript. For example, the following lines are both valid:
16
17 ```js
18 var name = "ESLint"
19 var website = "eslint.org";
20 ```
21
22 On the first line, the JavaScript engine will automatically insert a semicolon, so this is not considered a syntax error. The JavaScript engine still knows how to interpret the line and knows that the line end indicates the end of the statement.
23
24 In the debate over ASI, there are generally two schools of thought. The first is that we should treat ASI as if it didn't exist and always include semicolons manually. The rationale is that it's easier to always include semicolons than to try to remember when they are or are not required, and thus decreases the possibility of introducing an error.
25
26 However, the ASI mechanism can sometimes be tricky to people who are using semicolons. For example, consider this code:
27
28 ```js
29 return
30 {
31 name: "ESLint"
32 };
33 ```
34
35 This may look like a `return` statement that returns an object literal, however, the JavaScript engine will interpret this code as:
36
37 ```js
38 return;
39 {
40 name: "ESLint";
41 }
42 ```
43
44 Effectively, a semicolon is inserted after the `return` statement, causing the code below it (a labeled literal inside a block) to be unreachable. This rule and the [no-unreachable](no-unreachable) rule will protect your code from such cases.
45
46 On the other side of the argument are those who say that since semicolons are inserted automatically, they are optional and do not need to be inserted manually. However, the ASI mechanism can also be tricky to people who don't use semicolons. For example, consider this code:
47
48 ```js
49 var globalCounter = { }
50
51 (function () {
52 var n = 0
53 globalCounter.increment = function () {
54 return ++n
55 }
56 })()
57 ```
58
59 In this example, a semicolon will not be inserted after the first line, causing a run-time error (because an empty object is called as if it's a function). The [no-unexpected-multiline](no-unexpected-multiline) rule can protect your code from such cases.
60
61 Although ASI allows for more freedom over your coding style, it can also make your code behave in an unexpected way, whether you use semicolons or not. Therefore, it is best to know when ASI takes place and when it does not, and have ESLint protect your code from these potentially unexpected cases. In short, as once described by Isaac Schlueter, a `\n` character always ends a statement (just like a semicolon) unless one of the following is true:
62
63 1. The statement has an unclosed paren, array literal, or object literal or ends in some other way that is not a valid way to end a statement. (For instance, ending with `.` or `,`.)
64 1. The line is `--` or `++` (in which case it will decrement/increment the next token.)
65 1. It is a `for()`, `while()`, `do`, `if()`, or `else`, and there is no `{`
66 1. The next line starts with `[`, `(`, `+`, `*`, `/`, `-`, `,`, `.`, or some other binary operator that can only be found between two tokens in a single expression.
67
68 ## Rule Details
69
70 This rule enforces consistent use of semicolons.
71
72 ## Options
73
74 This rule has two options, a string option and an object option.
75
76 String option:
77
78 * `"always"` (default) requires semicolons at the end of statements
79 * `"never"` disallows semicolons at the end of statements (except to disambiguate statements beginning with `[`, `(`, `/`, `+`, or `-`)
80
81 Object option (when `"always"`):
82
83 * `"omitLastInOneLineBlock": true` disallows the last semicolon in a block in which its braces (and therefore the content of the block) are in the same line
84 * `"omitLastInOneLineClassBody": true` disallows the last semicolon in a class body in which its braces (and therefore the content of the class body) are in the same line
85
86 Object option (when `"never"`):
87
88 * `"beforeStatementContinuationChars": "any"` (default) ignores semicolons (or lacking semicolon) at the end of statements if the next line starts with `[`, `(`, `/`, `+`, or `-`.
89 * `"beforeStatementContinuationChars": "always"` requires semicolons at the end of statements if the next line starts with `[`, `(`, `/`, `+`, or `-`.
90 * `"beforeStatementContinuationChars": "never"` disallows semicolons at the end of statements if it doesn't make ASI hazard even if the next line starts with `[`, `(`, `/`, `+`, or `-`.
91
92 **Note:** `beforeStatementContinuationChars` does not apply to class fields because class fields are not statements.
93
94 ### always
95
96 Examples of **incorrect** code for this rule with the default `"always"` option:
97
98 ::: incorrect
99
100 ```js
101 /*eslint semi: ["error", "always"]*/
102
103 var name = "ESLint"
104
105 object.method = function() {
106 // ...
107 }
108
109 class Foo {
110 bar = 1
111 }
112 ```
113
114 :::
115
116 Examples of **correct** code for this rule with the default `"always"` option:
117
118 ::: correct
119
120 ```js
121 /*eslint semi: "error"*/
122
123 var name = "ESLint";
124
125 object.method = function() {
126 // ...
127 };
128
129 class Foo {
130 bar = 1;
131 }
132 ```
133
134 :::
135
136 #### omitLastInOneLineBlock
137
138 Examples of additional **correct** code for this rule with the `"always", { "omitLastInOneLineBlock": true }` options:
139
140 ::: correct
141
142 ```js
143 /*eslint semi: ["error", "always", { "omitLastInOneLineBlock": true}] */
144
145 if (foo) { bar() }
146
147 if (foo) { bar(); baz() }
148
149 function f() { bar(); baz() }
150
151 class C {
152 foo() { bar(); baz() }
153
154 static { bar(); baz() }
155 }
156 ```
157
158 :::
159
160 #### omitLastInOneLineClassBody
161
162 Examples of additional **correct** code for this rule with the `"always", { "omitLastInOneLineClassBody": true }` options:
163
164 ::: correct
165
166 ```js
167 /*eslint semi: ["error", "always", { "omitLastInOneLineClassBody": true}] */
168
169 export class SomeClass{
170 logType(){
171 console.log(this.type);
172 console.log(this.anotherType);
173 }
174 }
175
176 export class Variant1 extends SomeClass{type=1}
177 export class Variant2 extends SomeClass{type=2; anotherType=3}
178 ```
179
180 :::
181
182 ### never
183
184 Examples of **incorrect** code for this rule with the `"never"` option:
185
186 ::: incorrect
187
188 ```js
189 /*eslint semi: ["error", "never"]*/
190
191 var name = "ESLint";
192
193 object.method = function() {
194 // ...
195 };
196
197 class Foo {
198 bar = 1;
199 }
200 ```
201
202 :::
203
204 Examples of **correct** code for this rule with the `"never"` option:
205
206 ::: correct
207
208 ```js
209 /*eslint semi: ["error", "never"]*/
210
211 var name = "ESLint"
212
213 object.method = function() {
214 // ...
215 }
216
217 var name = "ESLint"
218
219 ;(function() {
220 // ...
221 })()
222
223 import a from "a"
224 (function() {
225 // ...
226 })()
227
228 import b from "b"
229 ;(function() {
230 // ...
231 })()
232
233 class Foo {
234 bar = 1
235 }
236 ```
237
238 :::
239
240 #### beforeStatementContinuationChars
241
242 Examples of additional **incorrect** code for this rule with the `"never", { "beforeStatementContinuationChars": "always" }` options:
243
244 ::: incorrect
245
246 ```js
247 /*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */
248 import a from "a"
249
250 (function() {
251 // ...
252 })()
253 ```
254
255 :::
256
257 Examples of additional **incorrect** code for this rule with the `"never", { "beforeStatementContinuationChars": "never" }` options:
258
259 ::: incorrect
260
261 ```js
262 /*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */
263 import a from "a"
264
265 ;(function() {
266 // ...
267 })()
268 ```
269
270 :::
271
272 ## When Not To Use It
273
274 If you do not want to enforce semicolon usage (or omission) in any particular way, then you can turn this rule off.