1 | # JavaScript Standard Style
|
2 |
|
3 | <p align="center">
|
4 | <a href="/docs/RULES-en.md">English</a> •
|
5 | <a href="/docs/RULES-esla.md">Español (Latinoamérica)</a> •
|
6 | <a href="/docs/RULES-fr.md">Français</a> •
|
7 | <a href="/docs/RULES-iteu.md">Italiano (Italian)</a> •
|
8 | <a href="/docs/RULES-ja.md">日本語 (Japanese)</a> •
|
9 | <a href="/docs/RULES-kokr.md">한국어 (Korean)</a> •
|
10 | <a href="/docs/RULES-ptbr.md">Português (Brasil)</a> •
|
11 | <a href="/docs/RULES-zhcn.md">简体中文 (Simplified Chinese)</a> •
|
12 | <a href="/docs/RULES-zhtw.md">繁體中文 (Taiwanese Mandarin)</a>
|
13 | </p>
|
14 |
|
15 | [![js-standard-style](https://cdn.rawgit.com/standard/standard/master/badge.svg)](https://github.com/standard/standard)
|
16 |
|
17 | This is a summary of the [standard](https://github.com/standard/standard) JavaScript
|
18 | rules.
|
19 |
|
20 | The best way to learn about `standard` is to just install it and give it a try on
|
21 | your code.
|
22 |
|
23 | ## Rules
|
24 |
|
25 | * **Use 2 spaces** for indentation.
|
26 |
|
27 | eslint: [`indent`](http://eslint.org/docs/rules/indent)
|
28 |
|
29 | ```js
|
30 | function hello (name) {
|
31 | console.log('hi', name)
|
32 | }
|
33 | ```
|
34 |
|
35 | * **Use single quotes for strings** except to avoid escaping.
|
36 |
|
37 | eslint: [`quotes`](http://eslint.org/docs/rules/quotes)
|
38 |
|
39 | ```js
|
40 | console.log('hello there') // ✓ ok
|
41 | console.log("hello there") // ✗ avoid
|
42 | console.log(`hello there`) // ✗ avoid
|
43 |
|
44 | $("<div class='box'>") // ✓ ok
|
45 | console.log(`hello ${name}`) // ✓ ok
|
46 | ```
|
47 |
|
48 | * **No unused variables.**
|
49 |
|
50 | eslint: [`no-unused-vars`](http://eslint.org/docs/rules/no-unused-vars)
|
51 |
|
52 | ```js
|
53 | function myFunction () {
|
54 | var result = something() // ✗ avoid
|
55 | }
|
56 | ```
|
57 |
|
58 | * **Add a space after keywords.**
|
59 |
|
60 | eslint: [`keyword-spacing`](http://eslint.org/docs/rules/keyword-spacing)
|
61 |
|
62 | ```js
|
63 | if (condition) { ... } // ✓ ok
|
64 | if(condition) { ... } // ✗ avoid
|
65 | ```
|
66 |
|
67 | * **Add a space before a function declaration's parentheses.**
|
68 |
|
69 | eslint: [`space-before-function-paren`](http://eslint.org/docs/rules/space-before-function-paren)
|
70 |
|
71 | ```js
|
72 | function name (arg) { ... } // ✓ ok
|
73 | function name(arg) { ... } // ✗ avoid
|
74 |
|
75 | run(function () { ... }) // ✓ ok
|
76 | run(function() { ... }) // ✗ avoid
|
77 | ```
|
78 |
|
79 | * **Always use** `===` instead of `==`.<br>
|
80 | Exception: `obj == null` is allowed to check for `null || undefined`.
|
81 |
|
82 | eslint: [`eqeqeq`](http://eslint.org/docs/rules/eqeqeq)
|
83 |
|
84 | ```js
|
85 | if (name === 'John') // ✓ ok
|
86 | if (name == 'John') // ✗ avoid
|
87 | ```
|
88 |
|
89 | ```js
|
90 | if (name !== 'John') // ✓ ok
|
91 | if (name != 'John') // ✗ avoid
|
92 | ```
|
93 |
|
94 | * **Infix operators** must be spaced.
|
95 |
|
96 | eslint: [`space-infix-ops`](http://eslint.org/docs/rules/space-infix-ops)
|
97 |
|
98 | ```js
|
99 | // ✓ ok
|
100 | var x = 2
|
101 | var message = 'hello, ' + name + '!'
|
102 | ```
|
103 |
|
104 | ```js
|
105 | // ✗ avoid
|
106 | var x=2
|
107 | var message = 'hello, '+name+'!'
|
108 | ```
|
109 |
|
110 | * **Commas should have a space** after them.
|
111 |
|
112 | eslint: [`comma-spacing`](http://eslint.org/docs/rules/comma-spacing)
|
113 |
|
114 | ```js
|
115 | // ✓ ok
|
116 | var list = [1, 2, 3, 4]
|
117 | function greet (name, options) { ... }
|
118 | ```
|
119 |
|
120 | ```js
|
121 | // ✗ avoid
|
122 | var list = [1,2,3,4]
|
123 | function greet (name,options) { ... }
|
124 | ```
|
125 |
|
126 | * **Keep else statements** on the same line as their curly braces.
|
127 |
|
128 | eslint: [`brace-style`](http://eslint.org/docs/rules/brace-style)
|
129 |
|
130 | ```js
|
131 | // ✓ ok
|
132 | if (condition) {
|
133 | // ...
|
134 | } else {
|
135 | // ...
|
136 | }
|
137 | ```
|
138 |
|
139 | ```js
|
140 | // ✗ avoid
|
141 | if (condition) {
|
142 | // ...
|
143 | }
|
144 | else {
|
145 | // ...
|
146 | }
|
147 | ```
|
148 |
|
149 | * **For multi-line if statements,** use curly braces.
|
150 |
|
151 | eslint: [`curly`](http://eslint.org/docs/rules/curly)
|
152 |
|
153 | ```js
|
154 | // ✓ ok
|
155 | if (options.quiet !== true) console.log('done')
|
156 | ```
|
157 |
|
158 | ```js
|
159 | // ✓ ok
|
160 | if (options.quiet !== true) {
|
161 | console.log('done')
|
162 | }
|
163 | ```
|
164 |
|
165 | ```js
|
166 | // ✗ avoid
|
167 | if (options.quiet !== true)
|
168 | console.log('done')
|
169 | ```
|
170 |
|
171 | * **Always handle the** `err` function parameter.
|
172 |
|
173 | eslint: [`handle-callback-err`](http://eslint.org/docs/rules/handle-callback-err)
|
174 | ```js
|
175 | // ✓ ok
|
176 | run(function (err) {
|
177 | if (err) throw err
|
178 | window.alert('done')
|
179 | })
|
180 | ```
|
181 |
|
182 | ```js
|
183 | // ✗ avoid
|
184 | run(function (err) {
|
185 | window.alert('done')
|
186 | })
|
187 | ```
|
188 |
|
189 | * **Declare browser globals** with a `/* global */` comment.<br>
|
190 | Exceptions are: `window`, `document`, and `navigator`.<br>
|
191 | Prevents accidental use of poorly-named browser globals like `open`, `length`,
|
192 | `event`, and `name`.
|
193 |
|
194 | ```js
|
195 | /* global alert, prompt */
|
196 |
|
197 | alert('hi')
|
198 | prompt('ok?')
|
199 | ```
|
200 |
|
201 | Explicitly referencing the function or property on `window` is okay too, though
|
202 | such code will not run in a Worker which uses `self` instead of `window`.
|
203 |
|
204 | eslint: [`no-undef`](http://eslint.org/docs/rules/no-undef)
|
205 |
|
206 | ```js
|
207 | window.alert('hi') // ✓ ok
|
208 | ```
|
209 |
|
210 | * **Multiple blank lines not allowed.**
|
211 |
|
212 | eslint: [`no-multiple-empty-lines`](http://eslint.org/docs/rules/no-multiple-empty-lines)
|
213 |
|
214 | ```js
|
215 | // ✓ ok
|
216 | var value = 'hello world'
|
217 | console.log(value)
|
218 | ```
|
219 |
|
220 | ```js
|
221 | // ✗ avoid
|
222 | var value = 'hello world'
|
223 |
|
224 |
|
225 | console.log(value)
|
226 | ```
|
227 |
|
228 | * **For the ternary operator** in a multi-line setting, place `?` and `:` on their own lines.
|
229 |
|
230 | eslint: [`operator-linebreak`](http://eslint.org/docs/rules/operator-linebreak)
|
231 |
|
232 | ```js
|
233 | // ✓ ok
|
234 | var location = env.development ? 'localhost' : 'www.api.com'
|
235 |
|
236 | // ✓ ok
|
237 | var location = env.development
|
238 | ? 'localhost'
|
239 | : 'www.api.com'
|
240 |
|
241 | // ✗ avoid
|
242 | var location = env.development ?
|
243 | 'localhost' :
|
244 | 'www.api.com'
|
245 | ```
|
246 |
|
247 | * **For var declarations,** write each declaration in its own statement.
|
248 |
|
249 | eslint: [`one-var`](http://eslint.org/docs/rules/one-var)
|
250 |
|
251 | ```js
|
252 | // ✓ ok
|
253 | var silent = true
|
254 | var verbose = true
|
255 |
|
256 | // ✗ avoid
|
257 | var silent = true, verbose = true
|
258 |
|
259 | // ✗ avoid
|
260 | var silent = true,
|
261 | verbose = true
|
262 | ```
|
263 |
|
264 | * **Wrap conditional assignments** with additional parentheses. This makes it clear that the expression is intentionally an assignment (`=`) rather than a typo for equality (`===`).
|
265 |
|
266 | eslint: [`no-cond-assign`](http://eslint.org/docs/rules/no-cond-assign)
|
267 |
|
268 | ```js
|
269 | // ✓ ok
|
270 | while ((m = text.match(expr))) {
|
271 | // ...
|
272 | }
|
273 |
|
274 | // ✗ avoid
|
275 | while (m = text.match(expr)) {
|
276 | // ...
|
277 | }
|
278 | ```
|
279 |
|
280 | * **Add spaces inside single line blocks.**
|
281 |
|
282 | eslint: [`block-spacing`](http://eslint.org/docs/rules/block-spacing)
|
283 |
|
284 | ```js
|
285 | function foo () {return true} // ✗ avoid
|
286 | function foo () { return true } // ✓ ok
|
287 | ```
|
288 |
|
289 | * **Use camelcase when naming variables and functions.**
|
290 |
|
291 | eslint: [`camelcase`](http://eslint.org/docs/rules/camelcase)
|
292 |
|
293 | ```js
|
294 | function my_function () { } // ✗ avoid
|
295 | function myFunction () { } // ✓ ok
|
296 |
|
297 | var my_var = 'hello' // ✗ avoid
|
298 | var myVar = 'hello' // ✓ ok
|
299 | ```
|
300 |
|
301 | * **Trailing commas not allowed.**
|
302 |
|
303 | eslint: [`comma-dangle`](http://eslint.org/docs/rules/comma-dangle)
|
304 |
|
305 | ```js
|
306 | var obj = {
|
307 | message: 'hello', // ✗ avoid
|
308 | }
|
309 | ```
|
310 |
|
311 | * **Commas must be placed at the end of the current line.**
|
312 |
|
313 | eslint: [`comma-style`](http://eslint.org/docs/rules/comma-style)
|
314 |
|
315 | ```js
|
316 | var obj = {
|
317 | foo: 'foo'
|
318 | ,bar: 'bar' // ✗ avoid
|
319 | }
|
320 |
|
321 | var obj = {
|
322 | foo: 'foo',
|
323 | bar: 'bar' // ✓ ok
|
324 | }
|
325 | ```
|
326 |
|
327 | * **Dot should be on the same line as property.**
|
328 |
|
329 | eslint: [`dot-location`](http://eslint.org/docs/rules/dot-location)
|
330 |
|
331 | ```js
|
332 | console.
|
333 | log('hello') // ✗ avoid
|
334 |
|
335 | console
|
336 | .log('hello') // ✓ ok
|
337 | ```
|
338 |
|
339 | * **Files must end with a newline.**
|
340 |
|
341 | eslint: [`eol-last`](http://eslint.org/docs/rules/eol-last)
|
342 |
|
343 | * **No space between function identifiers and their invocations.**
|
344 |
|
345 | eslint: [`func-call-spacing`](http://eslint.org/docs/rules/func-call-spacing)
|
346 |
|
347 | ```js
|
348 | console.log ('hello') // ✗ avoid
|
349 | console.log('hello') // ✓ ok
|
350 | ```
|
351 |
|
352 | * **Add space between colon and value in key value pairs.**
|
353 |
|
354 | eslint: [`key-spacing`](http://eslint.org/docs/rules/key-spacing)
|
355 |
|
356 | ```js
|
357 | var obj = { 'key' : 'value' } // ✗ avoid
|
358 | var obj = { 'key' :'value' } // ✗ avoid
|
359 | var obj = { 'key':'value' } // ✗ avoid
|
360 | var obj = { 'key': 'value' } // ✓ ok
|
361 | ```
|
362 |
|
363 | * **Constructor names must begin with a capital letter.**
|
364 |
|
365 | eslint: [`new-cap`](http://eslint.org/docs/rules/new-cap)
|
366 |
|
367 | ```js
|
368 | function animal () {}
|
369 | var dog = new animal() // ✗ avoid
|
370 |
|
371 | function Animal () {}
|
372 | var dog = new Animal() // ✓ ok
|
373 | ```
|
374 |
|
375 | * **Constructor with no arguments must be invoked with parentheses.**
|
376 |
|
377 | eslint: [`new-parens`](http://eslint.org/docs/rules/new-parens)
|
378 |
|
379 | ```js
|
380 | function Animal () {}
|
381 | var dog = new Animal // ✗ avoid
|
382 | var dog = new Animal() // ✓ ok
|
383 | ```
|
384 |
|
385 | * **Objects must contain a getter when a setter is defined.**
|
386 |
|
387 | eslint: [`accessor-pairs`](http://eslint.org/docs/rules/accessor-pairs)
|
388 |
|
389 | ```js
|
390 | var person = {
|
391 | set name (value) { // ✗ avoid
|
392 | this._name = value
|
393 | }
|
394 | }
|
395 |
|
396 | var person = {
|
397 | set name (value) {
|
398 | this._name = value
|
399 | },
|
400 | get name () { // ✓ ok
|
401 | return this._name
|
402 | }
|
403 | }
|
404 | ```
|
405 |
|
406 | * **Constructors of derived classes must call `super`.**
|
407 |
|
408 | eslint: [`constructor-super`](http://eslint.org/docs/rules/constructor-super)
|
409 |
|
410 | ```js
|
411 | class Dog {
|
412 | constructor () {
|
413 | super() // ✗ avoid
|
414 | }
|
415 | }
|
416 |
|
417 | class Dog extends Mammal {
|
418 | constructor () {
|
419 | super() // ✓ ok
|
420 | }
|
421 | }
|
422 | ```
|
423 |
|
424 | * **Use array literals instead of array constructors.**
|
425 |
|
426 | eslint: [`no-array-constructor`](http://eslint.org/docs/rules/no-array-constructor)
|
427 |
|
428 | ```js
|
429 | var nums = new Array(1, 2, 3) // ✗ avoid
|
430 | var nums = [1, 2, 3] // ✓ ok
|
431 | ```
|
432 |
|
433 | * **Avoid using `arguments.callee` and `arguments.caller`.**
|
434 |
|
435 | eslint: [`no-caller`](http://eslint.org/docs/rules/no-caller)
|
436 |
|
437 | ```js
|
438 | function foo (n) {
|
439 | if (n <= 0) return
|
440 |
|
441 | arguments.callee(n - 1) // ✗ avoid
|
442 | }
|
443 |
|
444 | function foo (n) {
|
445 | if (n <= 0) return
|
446 |
|
447 | foo(n - 1) // ✓ ok
|
448 | }
|
449 | ```
|
450 |
|
451 | * **Avoid modifying variables of class declarations.**
|
452 |
|
453 | eslint: [`no-class-assign`](http://eslint.org/docs/rules/no-class-assign)
|
454 |
|
455 | ```js
|
456 | class Dog {}
|
457 | Dog = 'Fido' // ✗ avoid
|
458 | ```
|
459 |
|
460 | * **Avoid modifying variables declared using `const`.**
|
461 |
|
462 | eslint: [`no-const-assign`](http://eslint.org/docs/rules/no-const-assign)
|
463 |
|
464 | ```js
|
465 | const score = 100
|
466 | score = 125 // ✗ avoid
|
467 | ```
|
468 |
|
469 | * **Avoid using constant expressions in conditions (except loops).**
|
470 |
|
471 | eslint: [`no-constant-condition`](http://eslint.org/docs/rules/no-constant-condition)
|
472 |
|
473 | ```js
|
474 | if (false) { // ✗ avoid
|
475 | // ...
|
476 | }
|
477 |
|
478 | if (x === 0) { // ✓ ok
|
479 | // ...
|
480 | }
|
481 |
|
482 | while (true) { // ✓ ok
|
483 | // ...
|
484 | }
|
485 | ```
|
486 |
|
487 | * **No control characters in regular expressions.**
|
488 |
|
489 | eslint: [`no-control-regex`](http://eslint.org/docs/rules/no-control-regex)
|
490 |
|
491 | ```js
|
492 | var pattern = /\x1f/ // ✗ avoid
|
493 | var pattern = /\x20/ // ✓ ok
|
494 | ```
|
495 |
|
496 | * **No `debugger` statements.**
|
497 |
|
498 | eslint: [`no-debugger`](http://eslint.org/docs/rules/no-debugger)
|
499 |
|
500 | ```js
|
501 | function sum (a, b) {
|
502 | debugger // ✗ avoid
|
503 | return a + b
|
504 | }
|
505 | ```
|
506 |
|
507 | * **No `delete` operator on variables.**
|
508 |
|
509 | eslint: [`no-delete-var`](http://eslint.org/docs/rules/no-delete-var)
|
510 |
|
511 | ```js
|
512 | var name
|
513 | delete name // ✗ avoid
|
514 | ```
|
515 |
|
516 | * **No duplicate arguments in function definitions.**
|
517 |
|
518 | eslint: [`no-dupe-args`](http://eslint.org/docs/rules/no-dupe-args)
|
519 |
|
520 | ```js
|
521 | function sum (a, b, a) { // ✗ avoid
|
522 | // ...
|
523 | }
|
524 |
|
525 | function sum (a, b, c) { // ✓ ok
|
526 | // ...
|
527 | }
|
528 | ```
|
529 |
|
530 | * **No duplicate name in class members.**
|
531 |
|
532 | eslint: [`no-dupe-class-members`](http://eslint.org/docs/rules/no-dupe-class-members)
|
533 |
|
534 | ```js
|
535 | class Dog {
|
536 | bark () {}
|
537 | bark () {} // ✗ avoid
|
538 | }
|
539 | ```
|
540 |
|
541 | * **No duplicate keys in object literals.**
|
542 |
|
543 | eslint: [`no-dupe-keys`](http://eslint.org/docs/rules/no-dupe-keys)
|
544 |
|
545 | ```js
|
546 | var user = {
|
547 | name: 'Jane Doe',
|
548 | name: 'John Doe' // ✗ avoid
|
549 | }
|
550 | ```
|
551 |
|
552 | * **No duplicate `case` labels in `switch` statements.**
|
553 |
|
554 | eslint: [`no-duplicate-case`](http://eslint.org/docs/rules/no-duplicate-case)
|
555 |
|
556 | ```js
|
557 | switch (id) {
|
558 | case 1:
|
559 | // ...
|
560 | case 1: // ✗ avoid
|
561 | }
|
562 | ```
|
563 |
|
564 | * **Use a single import statement per module.**
|
565 |
|
566 | eslint: [`no-duplicate-imports`](http://eslint.org/docs/rules/no-duplicate-imports)
|
567 |
|
568 | ```js
|
569 | import { myFunc1 } from 'module'
|
570 | import { myFunc2 } from 'module' // ✗ avoid
|
571 |
|
572 | import { myFunc1, myFunc2 } from 'module' // ✓ ok
|
573 | ```
|
574 |
|
575 | * **No empty character classes in regular expressions.**
|
576 |
|
577 | eslint: [`no-empty-character-class`](http://eslint.org/docs/rules/no-empty-character-class)
|
578 |
|
579 | ```js
|
580 | const myRegex = /^abc[]/ // ✗ avoid
|
581 | const myRegex = /^abc[a-z]/ // ✓ ok
|
582 | ```
|
583 |
|
584 | * **No empty destructuring patterns.**
|
585 |
|
586 | eslint: [`no-empty-pattern`](http://eslint.org/docs/rules/no-empty-pattern)
|
587 |
|
588 | ```js
|
589 | const { a: {} } = foo // ✗ avoid
|
590 | const { a: { b } } = foo // ✓ ok
|
591 | ```
|
592 |
|
593 | * **No using `eval()`.**
|
594 |
|
595 | eslint: [`no-eval`](http://eslint.org/docs/rules/no-eval)
|
596 |
|
597 | ```js
|
598 | eval( "var result = user." + propName ) // ✗ avoid
|
599 | var result = user[propName] // ✓ ok
|
600 | ```
|
601 |
|
602 | * **No reassigning exceptions in `catch` clauses.**
|
603 |
|
604 | eslint: [`no-ex-assign`](http://eslint.org/docs/rules/no-ex-assign)
|
605 |
|
606 | ```js
|
607 | try {
|
608 | // ...
|
609 | } catch (e) {
|
610 | e = 'new value' // ✗ avoid
|
611 | }
|
612 |
|
613 | try {
|
614 | // ...
|
615 | } catch (e) {
|
616 | const newVal = 'new value' // ✓ ok
|
617 | }
|
618 | ```
|
619 |
|
620 | * **No extending native objects.**
|
621 |
|
622 | eslint: [`no-extend-native`](http://eslint.org/docs/rules/no-extend-native)
|
623 |
|
624 | ```js
|
625 | Object.prototype.age = 21 // ✗ avoid
|
626 | ```
|
627 |
|
628 | * **Avoid unnecessary function binding.**
|
629 |
|
630 | eslint: [`no-extra-bind`](http://eslint.org/docs/rules/no-extra-bind)
|
631 |
|
632 | ```js
|
633 | const name = function () {
|
634 | getName()
|
635 | }.bind(user) // ✗ avoid
|
636 |
|
637 | const name = function () {
|
638 | this.getName()
|
639 | }.bind(user) // ✓ ok
|
640 | ```
|
641 |
|
642 | * **Avoid unnecessary boolean casts.**
|
643 |
|
644 | eslint: [`no-extra-boolean-cast`](http://eslint.org/docs/rules/no-extra-boolean-cast)
|
645 |
|
646 | ```js
|
647 | const result = true
|
648 | if (!!result) { // ✗ avoid
|
649 | // ...
|
650 | }
|
651 |
|
652 | const result = true
|
653 | if (result) { // ✓ ok
|
654 | // ...
|
655 | }
|
656 | ```
|
657 |
|
658 | * **No unnecessary parentheses around function expressions.**
|
659 |
|
660 | eslint: [`no-extra-parens`](http://eslint.org/docs/rules/no-extra-parens)
|
661 |
|
662 | ```js
|
663 | const myFunc = (function () { }) // ✗ avoid
|
664 | const myFunc = function () { } // ✓ ok
|
665 | ```
|
666 |
|
667 | * **Use `break` to prevent fallthrough in `switch` cases.**
|
668 |
|
669 | eslint: [`no-fallthrough`](http://eslint.org/docs/rules/no-fallthrough)
|
670 |
|
671 | ```js
|
672 | switch (filter) {
|
673 | case 1:
|
674 | doSomething() // ✗ avoid
|
675 | case 2:
|
676 | doSomethingElse()
|
677 | }
|
678 |
|
679 | switch (filter) {
|
680 | case 1:
|
681 | doSomething()
|
682 | break // ✓ ok
|
683 | case 2:
|
684 | doSomethingElse()
|
685 | }
|
686 |
|
687 | switch (filter) {
|
688 | case 1:
|
689 | doSomething()
|
690 | // fallthrough // ✓ ok
|
691 | case 2:
|
692 | doSomethingElse()
|
693 | }
|
694 | ```
|
695 |
|
696 | * **No floating decimals.**
|
697 |
|
698 | eslint: [`no-floating-decimal`](http://eslint.org/docs/rules/no-floating-decimal)
|
699 |
|
700 | ```js
|
701 | const discount = .5 // ✗ avoid
|
702 | const discount = 0.5 // ✓ ok
|
703 | ```
|
704 |
|
705 | * **Avoid reassigning function declarations.**
|
706 |
|
707 | eslint: [`no-func-assign`](http://eslint.org/docs/rules/no-func-assign)
|
708 |
|
709 | ```js
|
710 | function myFunc () { }
|
711 | myFunc = myOtherFunc // ✗ avoid
|
712 | ```
|
713 |
|
714 | * **No reassigning read-only global variables.**
|
715 |
|
716 | eslint: [`no-global-assign`](http://eslint.org/docs/rules/no-global-assign)
|
717 |
|
718 | ```js
|
719 | window = {} // ✗ avoid
|
720 | ```
|
721 |
|
722 | * **No implied `eval()`.**
|
723 |
|
724 | eslint: [`no-implied-eval`](http://eslint.org/docs/rules/no-implied-eval)
|
725 |
|
726 | ```js
|
727 | setTimeout("alert('Hello world')") // ✗ avoid
|
728 | setTimeout(function () { alert('Hello world') }) // ✓ ok
|
729 | ```
|
730 |
|
731 | * **No function declarations in nested blocks.**
|
732 |
|
733 | eslint: [`no-inner-declarations`](http://eslint.org/docs/rules/no-inner-declarations)
|
734 |
|
735 | ```js
|
736 | if (authenticated) {
|
737 | function setAuthUser () {} // ✗ avoid
|
738 | }
|
739 | ```
|
740 |
|
741 | * **No invalid regular expression strings in `RegExp` constructors.**
|
742 |
|
743 | eslint: [`no-invalid-regexp`](http://eslint.org/docs/rules/no-invalid-regexp)
|
744 |
|
745 | ```js
|
746 | RegExp('[a-z') // ✗ avoid
|
747 | RegExp('[a-z]') // ✓ ok
|
748 | ```
|
749 |
|
750 | * **No irregular whitespace.**
|
751 |
|
752 | eslint: [`no-irregular-whitespace`](http://eslint.org/docs/rules/no-irregular-whitespace)
|
753 |
|
754 | ```js
|
755 | function myFunc () /*<NBSP>*/{} // ✗ avoid
|
756 | ```
|
757 |
|
758 | * **No using `__iterator__`.**
|
759 |
|
760 | eslint: [`no-iterator`](http://eslint.org/docs/rules/no-iterator)
|
761 |
|
762 | ```js
|
763 | Foo.prototype.__iterator__ = function () {} // ✗ avoid
|
764 | ```
|
765 |
|
766 | * **No labels that share a name with an in scope variable.**
|
767 |
|
768 | eslint: [`no-label-var`](http://eslint.org/docs/rules/no-label-var)
|
769 |
|
770 | ```js
|
771 | var score = 100
|
772 | function game () {
|
773 | score: while (true) { // ✗ avoid
|
774 | score -= 10
|
775 | if (score > 0) continue score
|
776 | break
|
777 | }
|
778 | }
|
779 | ```
|
780 |
|
781 | * **No label statements.**
|
782 |
|
783 | eslint: [`no-labels`](http://eslint.org/docs/rules/no-labels)
|
784 |
|
785 | ```js
|
786 | label:
|
787 | while (true) {
|
788 | break label // ✗ avoid
|
789 | }
|
790 | ```
|
791 |
|
792 | * **No unnecessary nested blocks.**
|
793 |
|
794 | eslint: [`no-lone-blocks`](http://eslint.org/docs/rules/no-lone-blocks)
|
795 |
|
796 | ```js
|
797 | function myFunc () {
|
798 | { // ✗ avoid
|
799 | myOtherFunc()
|
800 | }
|
801 | }
|
802 |
|
803 | function myFunc () {
|
804 | myOtherFunc() // ✓ ok
|
805 | }
|
806 | ```
|
807 |
|
808 | * **Avoid mixing spaces and tabs for indentation.**
|
809 |
|
810 | eslint: [`no-mixed-spaces-and-tabs`](http://eslint.org/docs/rules/no-mixed-spaces-and-tabs)
|
811 |
|
812 | * **Do not use multiple spaces except for indentation.**
|
813 |
|
814 | eslint: [`no-multi-spaces`](http://eslint.org/docs/rules/no-multi-spaces)
|
815 |
|
816 | ```js
|
817 | const id = 1234 // ✗ avoid
|
818 | const id = 1234 // ✓ ok
|
819 | ```
|
820 |
|
821 | * **No multiline strings.**
|
822 |
|
823 | eslint: [`no-multi-str`](http://eslint.org/docs/rules/no-multi-str)
|
824 |
|
825 | ```js
|
826 | const message = 'Hello \
|
827 | world' // ✗ avoid
|
828 | ```
|
829 |
|
830 | * **No `new` without assigning object to a variable.**
|
831 |
|
832 | eslint: [`no-new`](http://eslint.org/docs/rules/no-new)
|
833 |
|
834 | ```js
|
835 | new Character() // ✗ avoid
|
836 | const character = new Character() // ✓ ok
|
837 | ```
|
838 |
|
839 | * **No using the `Function` constructor.**
|
840 |
|
841 | eslint: [`no-new-func`](http://eslint.org/docs/rules/no-new-func)
|
842 |
|
843 | ```js
|
844 | var sum = new Function('a', 'b', 'return a + b') // ✗ avoid
|
845 | ```
|
846 |
|
847 | * **No using the `Object` constructor.**
|
848 |
|
849 | eslint: [`no-new-object`](http://eslint.org/docs/rules/no-new-object)
|
850 |
|
851 | ```js
|
852 | let config = new Object() // ✗ avoid
|
853 | ```
|
854 |
|
855 | * **No using `new require`.**
|
856 |
|
857 | eslint: [`no-new-require`](http://eslint.org/docs/rules/no-new-require)
|
858 |
|
859 | ```js
|
860 | const myModule = new require('my-module') // ✗ avoid
|
861 | ```
|
862 |
|
863 | * **No using the `Symbol` constructor.**
|
864 |
|
865 | eslint: [`no-new-symbol`](http://eslint.org/docs/rules/no-new-symbol)
|
866 |
|
867 | ```js
|
868 | const foo = new Symbol('foo') // ✗ avoid
|
869 | ```
|
870 |
|
871 | * **No using primitive wrapper instances.**
|
872 |
|
873 | eslint: [`no-new-wrappers`](http://eslint.org/docs/rules/no-new-wrappers)
|
874 |
|
875 | ```js
|
876 | const message = new String('hello') // ✗ avoid
|
877 | ```
|
878 |
|
879 | * **No calling global object properties as functions.**
|
880 |
|
881 | eslint: [`no-obj-calls`](http://eslint.org/docs/rules/no-obj-calls)
|
882 |
|
883 | ```js
|
884 | const math = Math() // ✗ avoid
|
885 | ```
|
886 |
|
887 | * **No octal literals.**
|
888 |
|
889 | eslint: [`no-octal`](http://eslint.org/docs/rules/no-octal)
|
890 |
|
891 | ```js
|
892 | const num = 042 // ✗ avoid
|
893 | const num = '042' // ✓ ok
|
894 | ```
|
895 |
|
896 | * **No octal escape sequences in string literals.**
|
897 |
|
898 | eslint: [`no-octal-escape`](http://eslint.org/docs/rules/no-octal-escape)
|
899 |
|
900 | ```js
|
901 | const copyright = 'Copyright \251' // ✗ avoid
|
902 | ```
|
903 |
|
904 | * **Avoid string concatenation when using `__dirname` and `__filename`.**
|
905 |
|
906 | eslint: [`no-path-concat`](http://eslint.org/docs/rules/no-path-concat)
|
907 |
|
908 | ```js
|
909 | const pathToFile = __dirname + '/app.js' // ✗ avoid
|
910 | const pathToFile = path.join(__dirname, 'app.js') // ✓ ok
|
911 | ```
|
912 |
|
913 | * **Avoid using `__proto__`.** Use `getPrototypeOf` instead.
|
914 |
|
915 | eslint: [`no-proto`](http://eslint.org/docs/rules/no-proto)
|
916 |
|
917 | ```js
|
918 | const foo = obj.__proto__ // ✗ avoid
|
919 | const foo = Object.getPrototypeOf(obj) // ✓ ok
|
920 | ```
|
921 |
|
922 | * **No redeclaring variables.**
|
923 |
|
924 | eslint: [`no-redeclare`](http://eslint.org/docs/rules/no-redeclare)
|
925 |
|
926 | ```js
|
927 | let name = 'John'
|
928 | let name = 'Jane' // ✗ avoid
|
929 |
|
930 | let name = 'John'
|
931 | name = 'Jane' // ✓ ok
|
932 | ```
|
933 |
|
934 | * **Avoid multiple spaces in regular expression literals.**
|
935 |
|
936 | eslint: [`no-regex-spaces`](http://eslint.org/docs/rules/no-regex-spaces)
|
937 |
|
938 | ```js
|
939 | const regexp = /test value/ // ✗ avoid
|
940 |
|
941 | const regexp = /test {3}value/ // ✓ ok
|
942 | const regexp = /test value/ // ✓ ok
|
943 | ```
|
944 |
|
945 | * **Assignments in return statements must be surrounded by parentheses.**
|
946 |
|
947 | eslint: [`no-return-assign`](http://eslint.org/docs/rules/no-return-assign)
|
948 |
|
949 | ```js
|
950 | function sum (a, b) {
|
951 | return result = a + b // ✗ avoid
|
952 | }
|
953 |
|
954 | function sum (a, b) {
|
955 | return (result = a + b) // ✓ ok
|
956 | }
|
957 | ```
|
958 |
|
959 | * **Avoid assigning a variable to itself**
|
960 |
|
961 | eslint: [`no-self-assign`](http://eslint.org/docs/rules/no-self-assign)
|
962 |
|
963 | ```js
|
964 | name = name // ✗ avoid
|
965 | ```
|
966 |
|
967 | * **Avoid comparing a variable to itself.**
|
968 |
|
969 | eslint: [`no-self-compare`](http://eslint.org/docs/rules/no-self-compare)
|
970 |
|
971 | ```js
|
972 | if (score === score) {} // ✗ avoid
|
973 | ```
|
974 |
|
975 | * **Avoid using the comma operator.**
|
976 |
|
977 | eslint: [`no-sequences`](http://eslint.org/docs/rules/no-sequences)
|
978 |
|
979 | ```js
|
980 | if (doSomething(), !!test) {} // ✗ avoid
|
981 | ```
|
982 |
|
983 | * **Restricted names should not be shadowed.**
|
984 |
|
985 | eslint: [`no-shadow-restricted-names`](http://eslint.org/docs/rules/no-shadow-restricted-names)
|
986 |
|
987 | ```js
|
988 | let undefined = 'value' // ✗ avoid
|
989 | ```
|
990 |
|
991 | * **Sparse arrays are not allowed.**
|
992 |
|
993 | eslint: [`no-sparse-arrays`](http://eslint.org/docs/rules/no-sparse-arrays)
|
994 |
|
995 | ```js
|
996 | let fruits = ['apple',, 'orange'] // ✗ avoid
|
997 | ```
|
998 |
|
999 | * **Tabs should not be used**
|
1000 |
|
1001 | eslint: [`no-tabs`](http://eslint.org/docs/rules/no-tabs)
|
1002 |
|
1003 | * **Regular strings must not contain template literal placeholders.**
|
1004 |
|
1005 | eslint: [`no-template-curly-in-string`](http://eslint.org/docs/rules/no-template-curly-in-string)
|
1006 |
|
1007 | ```js
|
1008 | const message = 'Hello ${name}' // ✗ avoid
|
1009 | const message = `Hello ${name}` // ✓ ok
|
1010 | ```
|
1011 |
|
1012 | * **`super()` must be called before using `this`.**
|
1013 |
|
1014 | eslint: [`no-this-before-super`](http://eslint.org/docs/rules/no-this-before-super)
|
1015 |
|
1016 | ```js
|
1017 | class Dog extends Animal {
|
1018 | constructor () {
|
1019 | this.legs = 4 // ✗ avoid
|
1020 | super()
|
1021 | }
|
1022 | }
|
1023 | ```
|
1024 |
|
1025 | * **Only `throw` an `Error` object.**
|
1026 |
|
1027 | eslint: [`no-throw-literal`](http://eslint.org/docs/rules/no-throw-literal)
|
1028 |
|
1029 | ```js
|
1030 | throw 'error' // ✗ avoid
|
1031 | throw new Error('error') // ✓ ok
|
1032 | ```
|
1033 |
|
1034 | * **Whitespace not allowed at end of line.**
|
1035 |
|
1036 | eslint: [`no-trailing-spaces`](http://eslint.org/docs/rules/no-trailing-spaces)
|
1037 |
|
1038 | * **Initializing to `undefined` is not allowed.**
|
1039 |
|
1040 | eslint: [`no-undef-init`](http://eslint.org/docs/rules/no-undef-init)
|
1041 |
|
1042 | ```js
|
1043 | let name = undefined // ✗ avoid
|
1044 |
|
1045 | let name
|
1046 | name = 'value' // ✓ ok
|
1047 | ```
|
1048 |
|
1049 | * **No unmodified conditions of loops.**
|
1050 |
|
1051 | eslint: [`no-unmodified-loop-condition`](http://eslint.org/docs/rules/no-unmodified-loop-condition)
|
1052 |
|
1053 | ```js
|
1054 | for (let i = 0; i < items.length; j++) {...} // ✗ avoid
|
1055 | for (let i = 0; i < items.length; i++) {...} // ✓ ok
|
1056 | ```
|
1057 |
|
1058 | * **No ternary operators when simpler alternatives exist.**
|
1059 |
|
1060 | eslint: [`no-unneeded-ternary`](http://eslint.org/docs/rules/no-unneeded-ternary)
|
1061 |
|
1062 | ```js
|
1063 | let score = val ? val : 0 // ✗ avoid
|
1064 | let score = val || 0 // ✓ ok
|
1065 | ```
|
1066 |
|
1067 | * **No unreachable code after `return`, `throw`, `continue`, and `break` statements.**
|
1068 |
|
1069 | eslint: [`no-unreachable`](http://eslint.org/docs/rules/no-unreachable)
|
1070 |
|
1071 | ```js
|
1072 | function doSomething () {
|
1073 | return true
|
1074 | console.log('never called') // ✗ avoid
|
1075 | }
|
1076 | ```
|
1077 |
|
1078 | * **No flow control statements in `finally` blocks.**
|
1079 |
|
1080 | eslint: [`no-unsafe-finally`](http://eslint.org/docs/rules/no-unsafe-finally)
|
1081 |
|
1082 | ```js
|
1083 | try {
|
1084 | // ...
|
1085 | } catch (e) {
|
1086 | // ...
|
1087 | } finally {
|
1088 | return 42 // ✗ avoid
|
1089 | }
|
1090 | ```
|
1091 |
|
1092 | * **The left operand of relational operators must not be negated.**
|
1093 |
|
1094 | eslint: [`no-unsafe-negation`](http://eslint.org/docs/rules/no-unsafe-negation)
|
1095 |
|
1096 | ```js
|
1097 | if (!key in obj) {} // ✗ avoid
|
1098 | if (!(key in obj)) {} // ✓ ok
|
1099 | ```
|
1100 |
|
1101 | * **Avoid unnecessary use of `.call()` and `.apply()`.**
|
1102 |
|
1103 | eslint: [`no-useless-call`](http://eslint.org/docs/rules/no-useless-call)
|
1104 |
|
1105 | ```js
|
1106 | sum.call(null, 1, 2, 3) // ✗ avoid
|
1107 | ```
|
1108 |
|
1109 | * **Avoid using unnecessary computed property keys on objects.**
|
1110 |
|
1111 | eslint: [`no-useless-computed-key`](http://eslint.org/docs/rules/no-useless-computed-key)
|
1112 |
|
1113 | ```js
|
1114 | const user = { ['name']: 'John Doe' } // ✗ avoid
|
1115 | const user = { name: 'John Doe' } // ✓ ok
|
1116 | ```
|
1117 |
|
1118 | * **No unnecessary constructor.**
|
1119 |
|
1120 | eslint: [`no-useless-constructor`](http://eslint.org/docs/rules/no-useless-constructor)
|
1121 |
|
1122 | ```js
|
1123 | class Car {
|
1124 | constructor () { // ✗ avoid
|
1125 | }
|
1126 | }
|
1127 | ```
|
1128 |
|
1129 | * **No unnecessary use of escape.**
|
1130 |
|
1131 | eslint: [`no-useless-escape`](http://eslint.org/docs/rules/no-useless-escape)
|
1132 |
|
1133 | ```js
|
1134 | let message = 'Hell\o' // ✗ avoid
|
1135 | ```
|
1136 |
|
1137 | * **Renaming import, export, and destructured assignments to the same name is not allowed.**
|
1138 |
|
1139 | eslint: [`no-useless-rename`](http://eslint.org/docs/rules/no-useless-rename)
|
1140 |
|
1141 | ```js
|
1142 | import { config as config } from './config' // ✗ avoid
|
1143 | import { config } from './config' // ✓ ok
|
1144 | ```
|
1145 |
|
1146 | * **No whitespace before properties.**
|
1147 |
|
1148 | eslint: [`no-whitespace-before-property`](http://eslint.org/docs/rules/no-whitespace-before-property)
|
1149 |
|
1150 | ```js
|
1151 | user .name // ✗ avoid
|
1152 | user.name // ✓ ok
|
1153 | ```
|
1154 |
|
1155 | * **No using `with` statements.**
|
1156 |
|
1157 | eslint: [`no-with`](http://eslint.org/docs/rules/no-with)
|
1158 |
|
1159 | ```js
|
1160 | with (val) {...} // ✗ avoid
|
1161 | ```
|
1162 |
|
1163 | * **Maintain consistency of newlines between object properties.**
|
1164 |
|
1165 | eslint: [`object-property-newline`](http://eslint.org/docs/rules/object-property-newline)
|
1166 |
|
1167 | ```js
|
1168 | const user = {
|
1169 | name: 'Jane Doe', age: 30,
|
1170 | username: 'jdoe86' // ✗ avoid
|
1171 | }
|
1172 |
|
1173 | const user = { name: 'Jane Doe', age: 30, username: 'jdoe86' } // ✓ ok
|
1174 |
|
1175 | const user = {
|
1176 | name: 'Jane Doe',
|
1177 | age: 30,
|
1178 | username: 'jdoe86'
|
1179 | } // ✓ ok
|
1180 | ```
|
1181 |
|
1182 | * **No padding within blocks.**
|
1183 |
|
1184 | eslint: [`padded-blocks`](http://eslint.org/docs/rules/padded-blocks)
|
1185 |
|
1186 | ```js
|
1187 | if (user) {
|
1188 | // ✗ avoid
|
1189 | const name = getName()
|
1190 |
|
1191 | }
|
1192 |
|
1193 | if (user) {
|
1194 | const name = getName() // ✓ ok
|
1195 | }
|
1196 | ```
|
1197 |
|
1198 | * **No whitespace between spread operators and their expressions.**
|
1199 |
|
1200 | eslint: [`rest-spread-spacing`](http://eslint.org/docs/rules/rest-spread-spacing)
|
1201 |
|
1202 | ```js
|
1203 | fn(... args) // ✗ avoid
|
1204 | fn(...args) // ✓ ok
|
1205 | ```
|
1206 |
|
1207 | * **Semicolons must have a space after and no space before.**
|
1208 |
|
1209 | eslint: [`semi-spacing`](http://eslint.org/docs/rules/semi-spacing)
|
1210 |
|
1211 | ```js
|
1212 | for (let i = 0 ;i < items.length ;i++) {...} // ✗ avoid
|
1213 | for (let i = 0; i < items.length; i++) {...} // ✓ ok
|
1214 | ```
|
1215 |
|
1216 | * **Must have a space before blocks.**
|
1217 |
|
1218 | eslint: [`space-before-blocks`](http://eslint.org/docs/rules/space-before-blocks)
|
1219 |
|
1220 | ```js
|
1221 | if (admin){...} // ✗ avoid
|
1222 | if (admin) {...} // ✓ ok
|
1223 | ```
|
1224 |
|
1225 | * **No spaces inside parentheses.**
|
1226 |
|
1227 | eslint: [`space-in-parens`](http://eslint.org/docs/rules/space-in-parens)
|
1228 |
|
1229 | ```js
|
1230 | getName( name ) // ✗ avoid
|
1231 | getName(name) // ✓ ok
|
1232 | ```
|
1233 |
|
1234 | * **Unary operators must have a space after.**
|
1235 |
|
1236 | eslint: [`space-unary-ops`](http://eslint.org/docs/rules/space-unary-ops)
|
1237 |
|
1238 | ```js
|
1239 | typeof!admin // ✗ avoid
|
1240 | typeof !admin // ✓ ok
|
1241 | ```
|
1242 |
|
1243 | * **Use spaces inside comments.**
|
1244 |
|
1245 | eslint: [`spaced-comment`](http://eslint.org/docs/rules/spaced-comment)
|
1246 |
|
1247 | ```js
|
1248 | //comment // ✗ avoid
|
1249 | // comment // ✓ ok
|
1250 |
|
1251 | /*comment*/ // ✗ avoid
|
1252 | /* comment */ // ✓ ok
|
1253 | ```
|
1254 |
|
1255 | * **No spacing in template strings.**
|
1256 |
|
1257 | eslint: [`template-curly-spacing`](http://eslint.org/docs/rules/template-curly-spacing)
|
1258 |
|
1259 | ```js
|
1260 | const message = `Hello, ${ name }` // ✗ avoid
|
1261 | const message = `Hello, ${name}` // ✓ ok
|
1262 | ```
|
1263 |
|
1264 | * **Use `isNaN()` when checking for `NaN`.**
|
1265 |
|
1266 | eslint: [`use-isnan`](http://eslint.org/docs/rules/use-isnan)
|
1267 |
|
1268 | ```js
|
1269 | if (price === NaN) { } // ✗ avoid
|
1270 | if (isNaN(price)) { } // ✓ ok
|
1271 | ```
|
1272 |
|
1273 | * **`typeof` must be compared to a valid string.**
|
1274 |
|
1275 | eslint: [`valid-typeof`](http://eslint.org/docs/rules/valid-typeof)
|
1276 |
|
1277 | ```js
|
1278 | typeof name === 'undefimed' // ✗ avoid
|
1279 | typeof name === 'undefined' // ✓ ok
|
1280 | ```
|
1281 |
|
1282 | * **Immediately Invoked Function Expressions (IIFEs) must be wrapped.**
|
1283 |
|
1284 | eslint: [`wrap-iife`](http://eslint.org/docs/rules/wrap-iife)
|
1285 |
|
1286 | ```js
|
1287 | const getName = function () { }() // ✗ avoid
|
1288 |
|
1289 | const getName = (function () { }()) // ✓ ok
|
1290 | const getName = (function () { })() // ✓ ok
|
1291 | ```
|
1292 |
|
1293 | * **The `*` in `yield*`expressions must have a space before and after.**
|
1294 |
|
1295 | eslint: [`yield-star-spacing`](http://eslint.org/docs/rules/yield-star-spacing)
|
1296 |
|
1297 | ```js
|
1298 | yield* increment() // ✗ avoid
|
1299 | yield * increment() // ✓ ok
|
1300 | ```
|
1301 |
|
1302 | * **Avoid Yoda conditions.**
|
1303 |
|
1304 | eslint: [`yoda`](http://eslint.org/docs/rules/yoda)
|
1305 |
|
1306 | ```js
|
1307 | if (42 === age) { } // ✗ avoid
|
1308 | if (age === 42) { } // ✓ ok
|
1309 | ```
|
1310 |
|
1311 | ## Semicolons
|
1312 |
|
1313 | * No semicolons. (see: [1](http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding), [2](http://inimino.org/%7Einimino/blog/javascript_semicolons), [3](https://www.youtube.com/watch?v=gsfbh17Ax9I))
|
1314 |
|
1315 | eslint: [`semi`](http://eslint.org/docs/rules/semi)
|
1316 |
|
1317 | ```js
|
1318 | window.alert('hi') // ✓ ok
|
1319 | window.alert('hi'); // ✗ avoid
|
1320 | ```
|
1321 |
|
1322 | * Never start a line with `(`, `[`, `` ` ``, or a handful of other unlikely possibilities.
|
1323 |
|
1324 | This is the only gotcha with omitting semicolons, and `standard` protects you from this potential issue.
|
1325 |
|
1326 | (The full list is: `[`, `(`, `` ` ``, `+`, `*`, `/`, `-`, `,`, `.`, but most of these will never appear at the start of a line in real code.)
|
1327 |
|
1328 | eslint: [`no-unexpected-multiline`](http://eslint.org/docs/rules/no-unexpected-multiline)
|
1329 |
|
1330 | ```js
|
1331 | // ✓ ok
|
1332 | ;(function () {
|
1333 | window.alert('ok')
|
1334 | }())
|
1335 |
|
1336 | // ✗ avoid
|
1337 | (function () {
|
1338 | window.alert('ok')
|
1339 | }())
|
1340 | ```
|
1341 |
|
1342 | ```js
|
1343 | // ✓ ok
|
1344 | ;[1, 2, 3].forEach(bar)
|
1345 |
|
1346 | // ✗ avoid
|
1347 | [1, 2, 3].forEach(bar)
|
1348 | ```
|
1349 |
|
1350 | ```js
|
1351 | // ✓ ok
|
1352 | ;`hello`.indexOf('o')
|
1353 |
|
1354 | // ✗ avoid
|
1355 | `hello`.indexOf('o')
|
1356 | ```
|
1357 |
|
1358 | Note: If you're often writing code like this, you may be trying to be too clever.
|
1359 |
|
1360 | Clever short-hands are discouraged, in favor of clear and readable expressions, whenever
|
1361 | possible.
|
1362 |
|
1363 | Instead of this:
|
1364 |
|
1365 | ```js
|
1366 | ;[1, 2, 3].forEach(bar)
|
1367 | ```
|
1368 |
|
1369 | This is strongly preferred:
|
1370 |
|
1371 | ```js
|
1372 | var nums = [1, 2, 3]
|
1373 | nums.forEach(bar)
|
1374 | ```
|
1375 |
|
1376 |
|
1377 | ## Helpful reading
|
1378 |
|
1379 | - [An Open Letter to JavaScript Leaders Regarding Semicolons][1]
|
1380 | - [JavaScript Semicolon Insertion – Everything you need to know][2]
|
1381 |
|
1382 | ##### And a helpful video:
|
1383 |
|
1384 | - [Are Semicolons Necessary in JavaScript? - YouTube][3]
|
1385 |
|
1386 | All popular code minifiers in use today use AST-based minification, so they can
|
1387 | handle semicolon-less JavaScript with no issues (since semicolons are not required
|
1388 | in JavaScript).
|
1389 |
|
1390 | ##### Excerpt from *["An Open Letter to JavaScript Leaders Regarding Semicolons"][1]*:
|
1391 |
|
1392 | > [Relying on automatic semicolon insertion] is quite safe, and perfectly valid JS that every browser understands. Closure compiler, yuicompressor, packer, and jsmin all can properly minify it. There is no performance impact anywhere.
|
1393 | >
|
1394 | > I am sorry that, instead of educating you, the leaders in this language community have given you lies and fear. That was shameful. I recommend learning how statements in JS are actually terminated (and in which cases they are not terminated), so that you can write code that you find beautiful.
|
1395 | >
|
1396 | > In general, `\n` ends a statement unless:
|
1397 | > 1. The statement has an unclosed paren, array literal, or object literal or ends in some
|
1398 | > other way that is not a valid way to end a statement. (For instance, ending with `.`
|
1399 | > or `,`.)
|
1400 | > 2. The line is `--` or `++` (in which case it will decrement/increment the next token.)
|
1401 | > 3. It is a `for()`, `while()`, `do`, `if()`, or `else`, and there is no `{`
|
1402 | > 4. The next line starts with `[`, `(`, `+`, `*`, `/`, `-`, `,`, `.`, or some other
|
1403 | > binary operator that can only be found between two tokens in a single expression.
|
1404 | >
|
1405 | > The first is pretty obvious. Even JSLint is ok with `\n` chars in JSON and parenthesized constructs, and with `var` statements that span multiple lines ending in `,`.
|
1406 | >
|
1407 | > The second is super weird. I’ve never seen a case (outside of these sorts of conversations) where you’d want to do write `i\n++\nj`, but, point of fact, that’s parsed as `i; ++j`, not `i++; j`.
|
1408 | >
|
1409 | > The third is well understood, if generally despised. `if (x)\ny()` is equivalent to `if (x) { y() }`. The construct doesn’t end until it reaches either a block, or a statement.
|
1410 | >
|
1411 | > `;` is a valid JavaScript statement, so `if(x);` is equivalent to `if(x){}` or, “If x, do nothing.” This is more commonly applied to loops where the loop check also is the update function. Unusual, but not unheard of.
|
1412 | >
|
1413 | > The fourth is generally the fud-inducing “oh noes, you need semicolons!” case. But, as it turns out, it’s quite easy to *prefix* those lines with semicolons if you don’t mean them to be continuations of the previous line. For example, instead of this:
|
1414 | >
|
1415 | > ```js
|
1416 | > foo();
|
1417 | > [1,2,3].forEach(bar);
|
1418 | > ```
|
1419 | >
|
1420 | > you could do this:
|
1421 | >
|
1422 | > ```js
|
1423 | > foo()
|
1424 | > ;[1,2,3].forEach(bar)
|
1425 | > ```
|
1426 | >
|
1427 | > The advantage is that the prefixes are easier to notice, once you are accustomed to never seeing lines starting with `(` or `[` without semis.
|
1428 |
|
1429 | [1]: http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding
|
1430 | [2]: http://inimino.org/~inimino/blog/javascript_semicolons
|
1431 | [3]: https://www.youtube.com/watch?v=gsfbh17Ax9I
|
1432 |
|
\ | No newline at end of file |