@@ -21,7 +21,7 @@ Software engineering principles, from Robert C. Martin's book
21
21
adapted for JavaScript. This is not a style guide. It's a guide to producing
22
22
readable, reusable, and refactorable software in JavaScript.
23
23
24
- Not every principle herein has to be strictly followed, and even less will be
24
+ Not every principle herein has to be strictly followed, and even fewer will be
25
25
universally agreed upon. These are guidelines and nothing more, but they are
26
26
ones codified over many years of collective experience by the authors of
27
27
* Clean Code* .
@@ -53,24 +53,6 @@ const yearMonthDay = moment().format('YYYY/MM/DD');
53
53
```
54
54
** [ ⬆ back to top] ( #table-of-contents ) **
55
55
56
- ### Use ES2015/ES6 constants when variable values do not change
57
- In the bad example, the variable can be changed.
58
- When you declare a constant, the variable should stay
59
- the same throughout the program.
60
-
61
-
62
- ** Bad:**
63
- ``` javascript
64
- var FIRST_US_PRESIDENT = " George Washington" ;
65
- ```
66
-
67
- ** Good** :
68
- ``` javascript
69
- const FIRST_US_PRESIDENT = " George Washington" ;
70
- ```
71
- ** [ ⬆ back to top] ( #table-of-contents ) **
72
-
73
-
74
56
### Use the same vocabulary for the same type of variable
75
57
76
58
** Bad:**
@@ -136,9 +118,9 @@ const locations = ['Austin', 'New York', 'San Francisco'];
136
118
locations .forEach ((l ) => {
137
119
doStuff ();
138
120
doSomeOtherStuff ();
139
- ...
140
- ...
141
- ...
121
+ // ...
122
+ // ...
123
+ // ...
142
124
// Wait, what is `l` for again?
143
125
dispatch (l);
144
126
});
@@ -150,9 +132,9 @@ const locations = ['Austin', 'New York', 'San Francisco'];
150
132
locations .forEach ((location ) => {
151
133
doStuff ();
152
134
doSomeOtherStuff ();
153
- ...
154
- ...
155
- ...
135
+ // ...
136
+ // ...
137
+ // ...
156
138
dispatch (location);
157
139
});
158
140
```
@@ -212,7 +194,7 @@ function createMicrobrewery(name) {
212
194
** [ ⬆ back to top] ( #table-of-contents ) **
213
195
214
196
## ** Functions**
215
- ### Function arguments (2 or less ideally)
197
+ ### Function arguments (2 or fewer ideally)
216
198
Limiting the amount of function parameters is incredibly important because it
217
199
makes testing your function easier. Having more than three leads to a
218
200
combinatorial explosion where you have to test tons of different cases with
@@ -231,7 +213,7 @@ lot of arguments.
231
213
** Bad:**
232
214
``` javascript
233
215
function createMenu (title , body , buttonText , cancellable ) {
234
- ...
216
+ // ...
235
217
}
236
218
```
237
219
@@ -245,7 +227,7 @@ const menuConfig = {
245
227
}
246
228
247
229
function createMenu (menuConfig ) {
248
- ...
230
+ // ...
249
231
}
250
232
251
233
```
@@ -353,7 +335,7 @@ function tokenize(code) {
353
335
const tokens = [];
354
336
REGEXES .forEach ((REGEX ) => {
355
337
statements .forEach ((statement ) => {
356
- tokens .push ( // ... );
338
+ tokens .push ( /* ... */ );
357
339
})
358
340
});
359
341
@@ -363,7 +345,7 @@ function tokenize(code) {
363
345
function lexer (tokens ) {
364
346
const ast = [];
365
347
tokens .forEach ((token ) => {
366
- ast .push ( // ... );
348
+ ast .push ( /* ... */ );
367
349
});
368
350
369
351
return ast;
@@ -391,7 +373,7 @@ code eligible for refactoring.
391
373
** Bad:**
392
374
``` javascript
393
375
function showDeveloperList (developers ) {
394
- developers .forEach (developers => {
376
+ developers .forEach (developer => {
395
377
const expectedSalary = developer .calculateExpectedSalary ();
396
378
const experience = developer .getExperience ();
397
379
const githubLink = developer .getGithubLink ();
@@ -459,7 +441,7 @@ function writeForumComment(subject, body) {
459
441
** Good** :
460
442
``` javascript
461
443
function writeForumComment (subject = ' No subject' , body = ' No text' ) {
462
- ...
444
+ // ...
463
445
}
464
446
465
447
```
@@ -529,13 +511,13 @@ function createFile(name, temp) {
529
511
530
512
** Good** :
531
513
``` javascript
532
- function createTempFile (name ) {
533
- fs .create (' ./temp/' + name);
534
- }
535
-
536
514
function createFile (name ) {
537
515
fs .create (name);
538
516
}
517
+
518
+ function createTempFile (name ) {
519
+ createFile (' ./temp/' + name);
520
+ }
539
521
```
540
522
** [ ⬆ back to top] ( #table-of-contents ) **
541
523
@@ -601,11 +583,11 @@ Array.prototype.diff = function(comparisonArray) {
601
583
const values = [];
602
584
const hash = {};
603
585
604
- for (let i of comparisonArray) {
586
+ for (const i of comparisonArray) {
605
587
hash[i] = true ;
606
588
}
607
589
608
- for (let i of this ) {
590
+ for (const i of this ) {
609
591
if (! hash[i]) {
610
592
values .push (i);
611
593
}
@@ -626,7 +608,6 @@ class SuperArray extends Array {
626
608
** [ ⬆ back to top] ( #table-of-contents ) **
627
609
628
610
### Favor functional programming over imperative programming
629
- If Haskell were an IPA then JavaScript would be an O'Douls. That is to say,
630
611
JavaScript isn't a functional language in the way that Haskell is, but it has
631
612
a functional flavor to it. Functional languages are cleaner and easier to test.
632
613
Favor this style of programming when you can.
@@ -685,7 +666,7 @@ const totalOutput = programmerOutput
685
666
** Bad:**
686
667
``` javascript
687
668
if (fsm .state === ' fetching' && isEmpty (listNode)) {
688
- // / ...
669
+ // ...
689
670
}
690
671
```
691
672
@@ -739,7 +720,7 @@ just do one thing.
739
720
** Bad:**
740
721
``` javascript
741
722
class Airplane {
742
- // ...
723
+ // ...
743
724
getCruisingAltitude () {
744
725
switch (this .type ) {
745
726
case ' 777' :
@@ -756,25 +737,25 @@ class Airplane {
756
737
** Good** :
757
738
``` javascript
758
739
class Airplane {
759
- // ...
740
+ // ...
760
741
}
761
742
762
743
class Boeing777 extends Airplane {
763
- // ...
744
+ // ...
764
745
getCruisingAltitude () {
765
746
return getMaxAltitude () - getPassengerCount ();
766
747
}
767
748
}
768
749
769
750
class AirForceOne extends Airplane {
770
- // ...
751
+ // ...
771
752
getCruisingAltitude () {
772
753
return getMaxAltitude ();
773
754
}
774
755
}
775
756
776
757
class Cessna extends Airplane {
777
- // ...
758
+ // ...
778
759
getCruisingAltitude () {
779
760
return getMaxAltitude () - getFuelExpenditure ();
780
761
}
@@ -814,7 +795,7 @@ you should consider using TypeScript. It is an excellent alternative to normal
814
795
JavaScript, as it provides you with static typing on top of standard JavaScript
815
796
syntax. The problem with manually type-checking normal JavaScript is that
816
797
doing it well requires so much extra verbiage that the faux "type-safety" you get
817
- doesn't make up for the lost readability. Keep your JavaScript, clean, write
798
+ doesn't make up for the lost readability. Keep your JavaScript clean, write
818
799
good tests, and have good code reviews. Otherwise, do all of that but with
819
800
TypeScript (which, like I said, is a great alternative!).
820
801
@@ -848,8 +829,8 @@ they are fixed if they can be.
848
829
** Bad:**
849
830
``` javascript
850
831
851
- // On old browsers, each iteration would be costly because `len ` would be
852
- // recomputed . In modern browsers, this is optimized.
832
+ // On old browsers, each iteration with uncached `list.length ` would be costly
833
+ // because of `list.length` recomputation . In modern browsers, this is optimized.
853
834
for (let i = 0 , len = list .length ; i < len; i++ ) {
854
835
// ...
855
836
}
@@ -916,7 +897,7 @@ server.
916
897
``` javascript
917
898
class BankAccount {
918
899
constructor () {
919
- this .balance = 1000 ;
900
+ this .balance = 1000 ;
920
901
}
921
902
}
922
903
@@ -930,14 +911,14 @@ bankAccount.balance = bankAccount.balance - 100;
930
911
``` javascript
931
912
class BankAccount {
932
913
constructor () {
933
- this .balance = 1000 ;
914
+ this .balance = 1000 ;
934
915
}
935
916
936
917
// It doesn't have to be prefixed with `get` or `set` to be a getter/setter
937
918
withdraw (amount ) {
938
- if (verifyAmountCanBeDeducted (amount)) {
939
- this .balance -= amount;
940
- }
919
+ if (verifyAmountCanBeDeducted (amount)) {
920
+ this .balance -= amount;
921
+ }
941
922
}
942
923
}
943
924
@@ -1148,12 +1129,12 @@ function renderLargeRectangles(rectangles) {
1148
1129
rectangles .forEach ((rectangle ) => {
1149
1130
rectangle .setWidth (4 );
1150
1131
rectangle .setHeight (5 );
1151
- let area = rectangle .getArea (); // BAD: Will return 25 for Square. Should be 20.
1132
+ const area = rectangle .getArea (); // BAD: Will return 25 for Square. Should be 20.
1152
1133
rectangle .render (area);
1153
1134
})
1154
1135
}
1155
1136
1156
- let rectangles = [new Rectangle (), new Rectangle (), new Square ()];
1137
+ const rectangles = [new Rectangle (), new Rectangle (), new Square ()];
1157
1138
renderLargeRectangles (rectangles);
1158
1139
```
1159
1140
@@ -1488,7 +1469,7 @@ class Car {
1488
1469
}
1489
1470
1490
1471
setMake (make ) {
1491
- this .name = name ;
1472
+ this .make = make ;
1492
1473
}
1493
1474
1494
1475
setModel (model ) {
@@ -1521,7 +1502,7 @@ class Car {
1521
1502
}
1522
1503
1523
1504
setMake (make ) {
1524
- this .name = name ;
1505
+ this .make = make ;
1525
1506
// NOTE: Returning this for chaining
1526
1507
return this ;
1527
1508
}
@@ -1914,9 +1895,9 @@ class PerformanceReview {
1914
1895
}
1915
1896
1916
1897
perfReview () {
1917
- getPeerReviews ();
1918
- getManagerReview ();
1919
- getSelfReview ();
1898
+ this . getPeerReviews ();
1899
+ this . getManagerReview ();
1900
+ this . getSelfReview ();
1920
1901
}
1921
1902
1922
1903
getManagerReview () {
@@ -1928,7 +1909,7 @@ class PerformanceReview {
1928
1909
}
1929
1910
}
1930
1911
1931
- let review = new PerformanceReview (user);
1912
+ const review = new PerformanceReview (user);
1932
1913
review .perfReview ();
1933
1914
```
1934
1915
@@ -1940,9 +1921,9 @@ class PerformanceReview {
1940
1921
}
1941
1922
1942
1923
perfReview () {
1943
- getPeerReviews ();
1944
- getManagerReview ();
1945
- getSelfReview ();
1924
+ this . getPeerReviews ();
1925
+ this . getManagerReview ();
1926
+ this . getSelfReview ();
1946
1927
}
1947
1928
1948
1929
getPeerReviews () {
@@ -1967,7 +1948,7 @@ class PerformanceReview {
1967
1948
}
1968
1949
}
1969
1950
1970
- let review = new PerformanceReview (employee);
1951
+ const review = new PerformanceReview (employee);
1971
1952
review .perfReview ();
1972
1953
```
1973
1954
@@ -2068,7 +2049,7 @@ proper indentation and formatting give the visual structure to your code.
2068
2049
// //////////////////////////////////////////////////////////////////////////////
2069
2050
// Scope Model Instantiation
2070
2051
// //////////////////////////////////////////////////////////////////////////////
2071
- const $scope .model = {
2052
+ $scope .model = {
2072
2053
menu: ' foo' ,
2073
2054
nav: ' bar'
2074
2055
};
@@ -2083,7 +2064,7 @@ const actions = function() {
2083
2064
2084
2065
** Good** :
2085
2066
``` javascript
2086
- const $scope .model = {
2067
+ $scope .model = {
2087
2068
menu: ' foo' ,
2088
2069
nav: ' bar'
2089
2070
};
@@ -2093,45 +2074,3 @@ const actions = function() {
2093
2074
}
2094
2075
```
2095
2076
** [ ⬆ back to top] ( #table-of-contents ) **
2096
-
2097
- ### Avoid legal comments in source files
2098
- That's what your ` LICENSE ` file at the top of your source tree is for.
2099
-
2100
- **Bad:**
2101
- ` ` ` javascript
2102
- /*
2103
- The MIT License (MIT)
2104
-
2105
- Copyright (c) 2016 Ryan McDermott
2106
-
2107
- Permission is hereby granted, free of charge, to any person obtaining a copy
2108
- of this software and associated documentation files (the "Software"), to deal
2109
- in the Software without restriction, including without limitation the rights
2110
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2111
- copies of the Software, and to permit persons to whom the Software is
2112
- furnished to do so, subject to the following conditions:
2113
-
2114
- The above copyright notice and this permission notice shall be included in all
2115
- copies or substantial portions of the Software.
2116
-
2117
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2118
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2119
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2120
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2122
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2123
- SOFTWARE
2124
- */
2125
-
2126
- function calculateBill () {
2127
- // ...
2128
- }
2129
- ` ` `
2130
-
2131
- **Good**:
2132
- ` ` ` javascript
2133
- function calculateBill () {
2134
- // ...
2135
- }
2136
- ` ` `
2137
- **[⬆ back to top](#table-of-contents)**
0 commit comments