지난번 "무색의 초록 개념들이 격렬하게 잔다."라는 문장을 빗대어, 코드에 의미를 담는 것이 중요하다.라는 이야기를 하였다.
그럼, 코드에 의미를 어떻게 담아볼 수 있을까? 간단하게 다섯가지를 한 번 소개 해보겠다.
1. 변수명 잘 짓기
const boardList = {
count: 5,
list: [{boardId: 1, title: 'test', contents: '안녕하세요.'},
{boardId: 2, title: 'test', contents: '안녕하세요.'},
{boardId: 3, title: 'test', contents: '안녕하세요.'},
{boardId: 4, title: 'test', contents: '안녕하세요.'},
{boardId: 5, title: 'test', contents: '안녕하세요.'}]
}
자 위의 코드가 무엇이 잘못 되었을까? boardList list라는 단어를 사용 하였지만, boardList는 Object이다. 우리가 list라고 말할 수 있는 데이터 타입은 순서가 있는 자료구조들을 뜻하기 때문에, key, value 형태의 자료구조인 object에 list라고 명명하는 것은 좋지 않다.
2. 고차 함수 사용 시 주의하기
const nameList = [
{firstName: '길동', lastName: '홍'},
{firstName: '길은', lastName: '홍'},
{firstName: '길금', lastName: '홍'},
{firstName: '길동', lastName: '청'},
{firstName: '길은', lastName: '홍'}
]
function setFullName(nameInfo) {
return {...nameInfo, fullName:`${nameInfo.lastName}${nameInfo.firstName}`}
}
nameList.map(setFullName)
과연 위의 코드에 어떤 의미를 더 추가해줄 수 있을까? 일단, setFullName은 좋은 함수명은 아닌것 같긴 하지만... 일단 넘어가자 가장 큰 문제는
nameList.map(setFullName)
이 부분이라고 생각한다. setFullName에 어떤 인자를 사용하는지, 알 수가 없다.
nameList.map((nameInfo) => setFullName(nameInfo))
이처럼 변경만 해주어도, idx, list파라미터를 사용하지 않는 다는 것을 다른 개발자들에게 힌트를 줄 수 있다.
3. 문자열 합성 때, + 연산자 사용 하지 않기.
const test = 'test'
console.log(0 + test)
위 처럼만 보면 "0test"라는 결과를 나타낼 것이라는 것을 알 수 있다. 하지만...
console.log(0 + test)
이렇게만 노출 된다면, 결과값이 문자열인지? 숫자인지 알수가 없다. +연사자는 default힌트이기 때문에, 숫자로도 표현이 가능하다.
console.log(`0${test}`)
이렇게만 해주더라도, 결과값이 문자열이겠구나 라고 test변수를 추적하지 않아도, 알수가 있다.
4. 선언형 프로그래밍 방식을 사용 하자.
const nameList = [
{firstName: '길동', lastName: '홍'},
{firstName: '길은', lastName: '홍'},
{firstName: '길금', lastName: '홍'},
{firstName: '길동', lastName: '청'},
{firstName: '길은', lastName: '홍'}
]
const processNameList = []
for (const nameInfo of nameList) {
processNameList.push({
...nameInfo,
fullName: `${nameInfo.lastName}${nameInfo.firstName}`
})
}
자 위의 코드는 절차적 프로그래밍 방식으로 for문을 사용하여, 프로그래밍을 해본 방식으로, for문 안쪽을 살펴 보아야, 데이터의 변경을 수행 한다라는 것을 알 수 있다.
const nameList = [
{firstName: '길동', lastName: '홍'},
{firstName: '길은', lastName: '홍'},
{firstName: '길금', lastName: '홍'},
{firstName: '길동', lastName: '청'},
{firstName: '길은', lastName: '홍'}
]
const processNameList = nameList.map((nameInfo) => setFullName(nameInfo))
하지만 선언형 프로그래밍 방식으로 프로그래밍을 하면, map이라는 순회 메서드를 사용 하기 때문에, 바로 데이터를 형변환 시킨다는 것을 알수가 있다.
5. 의미에 맞는 순회 메서드를 사용 하자.
const nameList = [
{firstName: '길동', lastName: '홍'},
{firstName: '길은', lastName: '홍'},
{firstName: '길금', lastName: '홍'},
{firstName: '길동', lastName: '청'},
{firstName: '길은', lastName: '홍'}
]
const hasHong = nameList.filter(({lastName}) => lastName === '홍')
if(hasHong.length) {
//blah
}
자, 일단 hasHong이라는 변수는 홍씨가 있는지 확인하는 변수가로 생각하면 된다. 하지만, filter를 사용하고 있다. 일단 여기에는 첫번째 문제는 '홍'씨가 있는지 확인을 하기 위해서 리스트를 전부 순회하는 것이 문제가 된다.
const hasHong = nameList.find(({lastName}) => lastName === '홍')
if(hasHong) {
//blah
}
자 그러면 find로 바꾸어보자. 그러면 이때의 문제가 무엇일까? 성능상으로는 일단 모두 순회하지 않고, 홍씨를 찾는 순간 리턴 되기 때문에, 성능상이나 기능상으로는 문제가 되지 않지만, 다른 개발자들에게 hasHong.lastName, hasHong.firstName을 언젠가 참조할 것 같다라는 생각을 할 수 있게 한다.
const hasHong = nameList.some(({lastName}) => lastName === '홍')
적절하게 변경한다면, some의 경우 true/false 둘 중 하나만 리턴을 하기 때문에 위처럼 변경해야 불안요소를 전부 없앤 코드가 된다.
댓글
댓글 쓰기