@@ -55,7 +55,7 @@ const yyyymmdstr = moment().format('YYYY/MM/DD');
55
55
56
56
** 좋은 예:**
57
57
``` javascript
58
- const yearMonthDay = moment ().format (' YYYY/MM/DD' );
58
+ const currentDate = moment ().format (' YYYY/MM/DD' );
59
59
```
60
60
** [ ⬆ 상단으로] ( #목차 ) **
61
61
@@ -85,34 +85,30 @@ getUser();
85
85
** 안좋은 예:**
86
86
``` javascript
87
87
// 대체 86400000 무엇을 의미하는 걸까요?
88
- setTimeout (() => {
89
- this .blastOff ();
90
- }, 86400000 );
88
+ setTimeout (blastOff, 86400000 );
91
89
```
92
90
93
91
** 좋은 예**
94
92
``` javascript
95
93
// 대문자로 `const` 전역 변수를 선언하세요
96
94
const MILLISECONDS_IN_A_DAY = 86400000 ;
97
- setTimeout (() => {
98
- this .blastOff ();
99
- }, MILLISECONDS_IN_A_DAY );
95
+ setTimeout (blastOff, MILLISECONDS_IN_A_DAY );
100
96
```
101
97
** [ ⬆ 상단으로] ( #목차 ) **
102
98
103
99
### 의도를 나타내는 변수들을 사용하세요
104
100
** 안좋은 예:**
105
101
``` javascript
106
102
const address = ' One Infinite Loop, Cupertino 95014' ;
107
- const cityStateRegex = / ^ [^ ,\\ ] + [,\\ \s ] + (. +? )\s * (\d {5} )? $ / ;
108
- saveCityState (address .match (cityStateRegex )[1 ], address .match (cityStateRegex )[2 ]);
103
+ const cityZipCodeRegex = / ^ [^ ,\\ ] + [,\\ \s ] + (. +? )\s * (\d {5} )? $ / ;
104
+ saveCityZipCode (address .match (cityZipCodeRegex )[1 ], address .match (cityZipCodeRegex )[2 ]);
109
105
```
110
-
111
106
** 좋은 예:**
112
107
``` javascript
113
108
const address = ' One Infinite Loop, Cupertino 95014' ;
114
- const cityStateRegex = / ^ [^ ,\\ ] + [,\\ \s ] + (. +? )\s * (\d {5} )? $ / ;
115
- const [, city , state ] = address .match (cityStateRegex);
109
+ const cityZipCodeRegex = / ^ [^ ,\\ ] + [,\\ \s ] + (. +? )\s * (\d {5} )? $ / ;
110
+ const [, city , zipCode ] = address .match (cityZipCodeRegex);
111
+ saveCityZipCode (city, zipCode);
116
112
```
117
113
** [ ⬆ 상단으로] ( #목차 ) **
118
114
@@ -355,10 +351,22 @@ function parseBetterJSAlternative(code) {
355
351
** [ ⬆ 상단으로] ( #목차 ) **
356
352
357
353
### 중복된 코드를 작성하지 마세요
358
- 무조건 절대 어떤 상황에서도 중복된 코드를 작성하지 마세요. 당신이 프로페셔널한 개발자로서 커밋할때 저지를 수 있는 가장
359
- 큰 죄입니다. 중복된 코드가 있다는 것은 어떤 로직을 수정해야 할 일이 생겼을 때 수정 해야할 코드가 한 곳 이상이라는 것을 뜻합니다.
360
- JavaScript는 타입이 없는 언어이기 때문에 일반적인 함수를 만드는 것이 쉽습니다. [ jsinspect] ( https://github.com/danielstjules/jsinspect )
361
- 같은 도구를 이용해 리팩토링 가능한 중복된 코드들을 찾으세요.
354
+ 중복된 코드를 작성하지 않기위해 최선을 다하세요.
355
+ 중복된 코드가 있다는 것은 어떤 로직을 수정해야 할 일이 생겼을 때 수정 해야할 코드가 한 곳 이상이라는 것을 뜻합니다.
356
+
357
+ 만약 당신이 레스토랑을 운영하면서 토마토나 양파, 마늘, 고추같은 것들의 재고관리를 해야한다고 생각해보세요.
358
+ 재고가 적혀있는 종이가 여러장 있다면 토마토나 양파의 재고가 변동되었을 때 재고가 적혀있는 모든 종이를 수정해야 합니다.
359
+ 만약 재고를 관리하는 종이가 한 장이었다면 한 장의 재고 목록만 수정하면 됐겠죠!
360
+
361
+ 종종 코드를 살펴보면 사소한 몇몇의 차이점 때문에 중복된 코드를 작성한 경우가 있고
362
+ 이런 차이점들은 대부분 똑같은 일을 하는 분리된 함수들을 갖도록 강요합니다.
363
+ 즉 중복 코드를 제거한다는 것은 하나의 함수 / 모듈 / 클래스를 사용하여 이 여러 가지 사소한 차이점을 처리 할 수 있는
364
+ 추상화를 만드는 것을 의미합니다.
365
+
366
+ 그리고 추상화 할 부분이 남아있는 것은 위험하기때문에 * 클래스* 섹션에 제시된 여러 원칙들을 따라야 합니다.
367
+ 잘 추상화 하지 못한 코드는 중복된 코드보다 나쁠 수 있으므로 조심하세요. 즉 추상화를 잘 할 수 있다면
368
+ 그렇게 하라는 말입니다. 코드의 중복을 피한다면 여러분이 원할 때 언제든 한 곳만 수정해도 다른 모든 코드에
369
+ 반영되게 할 수 있습니다.
362
370
363
371
** 안좋은 예:**
364
372
``` javascript
@@ -544,28 +552,17 @@ JavaScript의 네이티브 Array 메소드를 확장하여 두 배열 간의 차
544
552
** 안좋은 예:**
545
553
``` javascript
546
554
Array .prototype .diff = function diff (comparisonArray ) {
547
- const values = [];
548
- const hash = {};
549
-
550
- for (const i of comparisonArray) {
551
- hash[i] = true ;
552
- }
553
-
554
- for (const i of this ) {
555
- if (! hash[i]) {
556
- values .push (i);
557
- }
558
- }
559
-
560
- return values;
555
+ const hash = new Set (comparisonArray);
556
+ return this .filter (elem => ! hash .has (elem));
561
557
};
562
558
```
563
559
564
560
** 좋은 예:**
565
561
``` javascript
566
562
class SuperArray extends Array {
567
563
diff (comparisonArray ) {
568
- return this .filter (elem => ! comparisonArray .includes (elem));
564
+ const hash = new Set (comparisonArray);
565
+ return this .filter (elem => ! hash .has (elem));
569
566
}
570
567
}
571
568
```
@@ -987,33 +984,80 @@ Bertrand Meyer에 말에 의하면 "소프트웨어 개체(클래스, 모듈,
987
984
988
985
** 안좋은 예:**
989
986
``` javascript
990
- class AjaxRequester {
987
+ class AjaxAdapter extends Adapter {
991
988
constructor () {
992
- // DELETE 같은 다른 HTTP METHOD를 추가하려면 어떻게 해야 할까요?
993
- // 우선 이 파일을 열어 배열에 직접 'DELETE'를 추가해야 합니다.
994
- this .HTTP_METHODS = [' POST' , ' PUT' , ' GET' ];
989
+ super ();
990
+ this .name = ' ajaxAdapter' ;
995
991
}
992
+ }
996
993
997
- get (url ) {
998
- // ...
994
+ class NodeAdapter extends Adapter {
995
+ constructor () {
996
+ super ();
997
+ this .name = ' nodeAdapter' ;
998
+ }
999
+ }
1000
+
1001
+ class HttpRequester {
1002
+ constructor (adapter ) {
1003
+ this .adapter = adapter;
1004
+ }
1005
+
1006
+ fetch (url ) {
1007
+ if (this .adapter .name === ' ajaxAdapter' ) {
1008
+ return makeAjaxCall (url).then ((response ) => {
1009
+ // transform response and return
1010
+ });
1011
+ } else if (this .adapter .name === ' httpNodeAdapter' ) {
1012
+ return makeHttpCall (url).then ((response ) => {
1013
+ // transform response and return
1014
+ });
1015
+ }
999
1016
}
1017
+ }
1018
+
1019
+ function makeAjaxCall (url ) {
1020
+ // request and return promise
1021
+ }
1000
1022
1023
+ function makeHttpCall (url ) {
1024
+ // request and return promise
1001
1025
}
1002
1026
```
1003
1027
1004
1028
** 좋은 예:**
1005
1029
``` javascript
1006
- class AjaxRequester {
1030
+ class AjaxAdapter extends Adapter {
1007
1031
constructor () {
1008
- this .HTTP_METHODS = [' POST' , ' PUT' , ' GET' ];
1032
+ super ();
1033
+ this .name = ' ajaxAdapter' ;
1009
1034
}
1010
1035
1011
- get (url ) {
1012
- // ...
1036
+ request (url ) {
1037
+ // request and return promise
1013
1038
}
1039
+ }
1014
1040
1015
- addHTTPMethod (method ) {
1016
- this .HTTP_METHODS .push (method);
1041
+ class NodeAdapter extends Adapter {
1042
+ constructor () {
1043
+ super ();
1044
+ this .name = ' nodeAdapter' ;
1045
+ }
1046
+
1047
+ request (url ) {
1048
+ // request and return promise
1049
+ }
1050
+ }
1051
+
1052
+ class HttpRequester {
1053
+ constructor (adapter ) {
1054
+ this .adapter = adapter;
1055
+ }
1056
+
1057
+ fetch (url ) {
1058
+ return this .adapter .request (url).then ((response ) => {
1059
+ // transform response and return
1060
+ });
1017
1061
}
1018
1062
}
1019
1063
```
@@ -1387,10 +1431,8 @@ class Human extends Mammal {
1387
1431
** [ ⬆ 상단으로] ( #목차 ) **
1388
1432
1389
1433
### 메소드 체이닝을 사용하세요
1390
- 이 원칙은 ` Clean Code ` 책에는 위배되는 것이지만 우리는 이번만큼은 이 원칙을 따라야합니다.
1391
- 메소드 체이닝은 항상 더럽고 [ 디미터 법칙(Law of Demeter)] ( https://en.wikipedia.org/wiki/Law_of_Demeter )
1392
- 을 위반한다고 항상 논의되어왔습니다. 물론 맞는 말이지만 JavaScript에서 메소드 체이닝은 매우 유용한 패턴이며
1393
- jQuery나 Lodash같은 많은 라이브러리에서 이 패턴을 찾아볼 수 있습니다. 이는 코드를 간결하고 이해하기 쉽게 만들어줍니다.
1434
+ JavaScript에서 메소드 체이닝은 매우 유용한 패턴이며 jQuery나 Lodash같은 많은 라이브러리에서 이 패턴을 찾아볼 수 있습니다.
1435
+ 이는 코드를 간결하고 이해하기 쉽게 만들어줍니다.
1394
1436
이런 이유들로 메소드 체이닝을 쓰는 것을 권하고, 사용해본뒤 얼마나 코드가 깔끔해졌는지 꼭 확인 해보길 바랍니다.
1395
1437
클래스 함수에서 단순히 모든 함수의 끝에 'this'를 리턴해주는 것으로 클래스 메소드를 추가로 연결할 수 있습니다.
1396
1438
@@ -1657,11 +1699,8 @@ require('request-promise').get('https://en.wikipedia.org/wiki/Robert_Cecil_Marti
1657
1699
``` javascript
1658
1700
async function getCleanCodeArticle () {
1659
1701
try {
1660
- const request = await require (' request-promise' );
1661
- const response = await request .get (' https://en.wikipedia.org/wiki/Robert_Cecil_Martin' );
1662
- const fileHandle = await require (' fs-promise' );
1663
-
1664
- await fileHandle .writeFile (' article.html' , response);
1702
+ const response = await require (' request-promise' ).get (' https://en.wikipedia.org/wiki/Robert_Cecil_Martin' );
1703
+ await require (' fs-promise' ).writeFile (' article.html' , response);
1665
1704
console .log (' File written' );
1666
1705
} catch (err) {
1667
1706
console .error (err);
@@ -1800,7 +1839,7 @@ class PerformanceReview {
1800
1839
return db .lookup (this .employee , ' peers' );
1801
1840
}
1802
1841
1803
- lookupMananger () {
1842
+ lookupManager () {
1804
1843
return db .lookup (this .employee , ' manager' );
1805
1844
}
1806
1845
@@ -1854,7 +1893,7 @@ class PerformanceReview {
1854
1893
const manager = this .lookupManager ();
1855
1894
}
1856
1895
1857
- lookupMananger () {
1896
+ lookupManager () {
1858
1897
return db .lookup (this .employee , ' manager' );
1859
1898
}
1860
1899
0 commit comments