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