Search
🛠️

리팩터링

1. 네이밍

1) 재사용성을 위한 함수 분리, 내 함수는 정말 한 가지 기능만 하는가?

function showTodos() { const todos = getTodos(); ... todos.forEach(todo => { console.log(todo); }); ... }
JavaScript
복사
위 코드는 아래와 같이 분리될 수 있습니다.
function logTodos(todos) { todos.forEach(todo => { console.log(todo); }); } function showTodos() { const todos = getTodos(); ... logTodos(todos); ... }
JavaScript
복사

2) 중간 변수 도입: 의미가 명확해진다면 변수명은 길어도 괜찮습니다.

const todos = getTodos(); todos.map(todo => { if (todo.completed) { ... } })
JavaScript
복사
const todos = getTodos(); const completedTodos = todos.filter(todo => todo.completed) if (completedTodos) { ... }
JavaScript
복사
복잡한 계산이 필요하다면 함수로 분리하면 좋습니다.

2. 구조

1) 빠른 실패: fast fail

빠른 실패를 하게끔 코드를 구현하면 depth를 줄일 수 있습니다.
if (성공로직) { ... } // 아래와 같이 빠른 실패를 하면 코드의 의도와 예외 조건이 명확해지고 나중에 분리하기도 쉽습니다. if (실패로직) { return } ... // 성공 로직
JavaScript
복사

2) boolean을 return한다면 바로 return하기

// bad if (isConfirmed) { return true } return false // good return isConfirmed
JavaScript
복사

3. 객체

1) 반복문 보다는 파이프

반복문 보다는 파이프를 이용한 경우 보다 읽기 좋은 코드가 될 경우가 많습니다.
가능하면 for문 대신에 내장 객체 메서드를 사용해주세요
find some every includes map filter reduce
JavaScript
복사
const completedTodos = []; for (const todo of todos) { if (todo.completed) { completedTodos.push(todo); } } const completedTodos = todos.filter(todo => todo.completed);
JavaScript
복사

2) switch 대신 object literal

function translateStatus(status) { switch(status) { case 'all': console.log('모두') break case 'active': console.log('해야할 일') break case 'completed': console.log('완료한 일') break } } //아래와 같이 object로 관리하면, 수정 및 관리에 있어서 더욱 간편해집니다. function translateStatus(status) { const statusList = { all: '모두', active: '해야할 일', completed: '완료한 일' }; console.log(statusList[status]) }
JavaScript
복사

3) 배열이나 객체는 forEach보다는 map을 이용해 불변 객체처럼 다루기

불변 객체로 다룬다면 데이터의 변화를 추적하기도 쉽고, 예상치 못한 데이터의 변경을 예방할 수 있습니다. forEach의 경우 기존 배열이나 객체에 변경을 가하는 메서드이기 때문에, forEach를 반드시 써야하는 경우가 아니라면 새로운 배열을 리턴하는 map을 활용해주세요~!
const menus = ['에스프레소', '카페라떼', '프라푸치노', '블랙티']; menus.forEach((value, index) => { menus[index] += '디카페인'; }); console.log(menus); to const menus = ['에스프레소', '카페라떼', '프라푸치노', '블랙티']; const decMenus = menus.map((value, index) => menus[index] += '디카페인'); console.log(decMenus);
JavaScript
복사

4. 기타

1) EOL (End of Line)

PR에서 이런 마크를 발견했다면! 환경에 따라 의도한 바와 다르게 개행 문자 처리가 되지 않도록 EOL 설정을 확인해주세요.

2) 주석에 담아야하는 대상

우리가 주석을 작성한다면 어떤걸 작성하면 좋을까요? 주석은 실제 코드를 포함하여 해당 부분을 이해하는데 더 많은 시간을 할애해야하고, 화면의 일정한 부분을 차지합니다. 그래서 주석 또한 코드의 일부이므로 작성할 때는 분명한 이유가 있어야 합니다. 그럼 작성해도 괜찮은 주석과, 그렇지 않은 주석 사이의 경계를 어떻게 정할 수 있을까요?

감독의 설명을 포함하기

영화에는 감독이 자신의 통찰을 설명하고, 영화가 만들어진 과정을 관람객이 잘 이해하게 도와주는 '감독의 설명'을 담은 감독판 트랙이 있습니다다. 이와 비슷한 방식으로 중요한 통찰을 기록한 주석을 코드에 포함시킨다면, 읽는 사람으로 하여금 해당 코드에 대한 더 높은 이해를 할 수 있게 도와줍니다.
예를 들면
// 이 데이터에서 이진트리는 해시테이블보다 40%정도 빠르다. // 재귀함수를 이용하면, 기존의 100line이 될수 있는 코드가 단 20줄로 정리된다. 반면 성능은 유의미한 차이가 없다.
JavaScript
복사
이러한 주석은 코드를 읽는 사람에게 코드를 최적화하느라 시간을 허비하지 않게 도와줍니다.

코드에 있는 결함을 설명하기

코드는 지속적으로 진화하며, 그러는 과정 중에 버그를 갖습니다. 이러한 결함을 설명하는 것을 부끄러워할 필요는 없습니다. 숨기는게 문제이지, 결함을 공개적으로 드러내고 수정할 여지를 남겨야 합니다. 예를 들어 개선이 필요할 때 아래와 같이 작성할 수 있습니다.
// TODO: JPEG외 다른 이미지 포맷도 처리할 수 있어야 한다
JavaScript
복사
// AsyncMode should be deprecated export function isAsyncMode(object: any) { if (__DEV__) { if (!hasWarnedAboutDeprecatedIsAsyncMode) { hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint console['warn']( 'The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 18+.', ); } } return false; }
JavaScript
복사
이러한 결함 설명과, 추가로 해야하는 일의 경우 팀내에서 컨벤션을 맞추면 좋습니다.

상수에 대한 설명

상수를 정의할 때는 종종 그 상수가 무엇을 하는지, 그것이 왜 특정한 값을 갖게 되는지 사연이 있는 경우가 있습니다. 예를 들면 아래와 같이 작성된 경우, 주석을 통해 해당 코드에 대한 이해도를 더 높게 가져갈 수 있습니다.
// 합리적인 한계 - 1000개 이상을 구독하는 사람은 기획 논의상 없다. const MAX_SUBSCRIPTIONS = 1000 // 사용자들은 0.72가 크기/해당도 대비 최선이라고 생각한다. const IMAGE_QUALITY = 0.72
JavaScript
복사

사람들이 쉽게 빠질 것 같은 함정을 미리 경고하기

예를 들어 사용자에게 이메일을 보내는 써드파티 라이브러리와 함수를 작성했다고 해봅시다. 이 때 아래와 같은 이슈가 있고, 그에 대해 작성해준다면, 함께 개발하는 사람은 1분정도 소요된다는걸 사용자에게 애니메이션이나, 메시지로 알림을 줄 수 있습니다. 그렇지 않다면, 왜 시간이 1분이나 걸리는지 그것이 에러가 아닌지 확인하는 작업을 해야할수도 있습니다.
// 이 함수는 외부 서비스를 호출하여, 이메일을 발송한다 (1분정도 소요) function sendEmail() { ... }
JavaScript
복사