[Javascript] 금융앱 토이 프로젝트 - 리팩토링

JY·2022년 5월 15일
0

Javascript 프로젝트

목록 보기
2/2


💡 리팩토링


  • import용 파일 생성
  • 용도에 따른 js 파일 분리
    • JSON 데이터 처리
    • 이벤트 처리
    • chart.js 라이브러리
  • <footer><nav> 변경
  • className, classList.add, setAttribute
  • JSON 데이터 처리 부분 구조 변경
  • 중복되는 코드 간소화
    • 날짜 불러오기
    • 지출 합계 계산
  • 불필요한 코드 삭제
  • 함수 선언 위치 변경

하단에 위치한다고 해서 무조건 <footer>가 아니다. 위치로 선택하는 것이 아닌 의미에 집중해야 한다. 따라서 이 프로젝트에서는 <footer>보다는 <nav>가 더 적절하다.

🤔 <footer> vs <nav>

  • <footer>: HTML 문서의 푸터(footer)에는 일반적으로 사이트의 작성자나 그에 따른 저작권 정보, 연락처 등을 명시한다.
  • <nav>: <nav> 태그는 다른 페이지 또는 현재 페이지의 다른 부분과 연결되는 네비게이션 링크(navigation links)들의 집합을 정의할 때 사용한다. <nav> 요소를 사용하는 일반적인 예로는 메뉴, 목차, 인덱스 등이 있다.

className, classList, setAttribute

  • className: 기존 클래스가 사라진다.
  • classList: 기존 클래스가 남아있고, 추가된다.
    • 배열에 클래스가 담기는 것이다. 그래서 기존 클래스가 그대로 남아있을 수 있는 것이다.
      class=”a b c” → 0: “a”, 1: “b”, 2: “c”

🤔 또한, classList는 오해의 여지도 있다..!
ulclassList를 썼네? 나중에 하나 클래스 더 들어오네 → 왜 한번에 안 넣었을까? → 컨텐츠가 안 들어가서 안 넣었구나. → 남은 클래스는 애니메이션에 관련된 클래스겠네?

따라서 클래스를 하나만 사용할 때는 className이나 setAttribute를 사용하는 것이 더 빠르고, 오해의 여지가 없다.

구조 변경

처음엔 데이터를 받아와서 그 자체로 사용하려고 했다. (날짜 별로 ul 태그 생성하고, li 태그 생성하고, li 태그 자식으로 들어가는 span 등의 태그 생성하고..) 그러다보니 코드도 너~무 길어지고 구조도 복잡해지고, 결정적으로는 매일 지출 합계를 계산해야 하는데 그곳에서 문제가 발생했다. 그래서 구조를 변경하게 되었다. 처음 짰던 코드는 너무 더럽고 길어서 여기에 올리기도 그렇다..

그래서! 받아온 데이터를 그대로 사용하는 것이 아닌, 먼저 데이터를 날짜 별로 나누는 작업이 필요했다. map을 돌면서 날짜 데이터만 받아온 뒤, 중복을 제거하여 uniqueDate에 날짜를 배열로 저장하였다. 그리고 날짜만큼 for문을 돌면서 filter로 각 날짜에 해당하는 객체만을 가져와서 배열에 넣어주었다. 다음과 같은 형태이다. 하나의 배열이 하나의 날짜이고, 그 날짜에 해당되는 데이터들이 모두 객체로 들어가있다.

이제 이것을 각 객체에 접근하여 데이터를 사용할 수 있도록 for...of를 이용해서 다음과 같은 형태로 만들어 주었다.

const getDatatoDate = (obj, date) => {
  return obj.filter((element) => {
    return element.date == date;
  })
};

function printData(obj) {
  const uniqueDate = [...new Set(obj.map((element) => element.date))];
  for(let i =0; i < uniqueDate.length; i++){
    let selectDate = uniqueDate[i];
    let selectObj = getDatatoDate(obj, uniqueDate[i]);
    for(const elem of selectObj){
      console.log(elem);
  }
  console.log("하루끝!")
}

정상적으로 작동은 하지만 이상한(?) 코드 수정

급하게 마무리 하느라 함수에 인자가 이런 식으로 들어가는 줄도 몰랐다.😅 (신기하게도 문제 없이 잘 작동한다.) 피드백을 받고나서야 '함수에 인자를 이렇게 넣었다고..?'라고 생각한 코드..

span_price.textContent = priceToString("+ "+elem.price);

span_price.textContent = `+ ${priceToString(elem.price)}`;

중복되는 코드 간소화

날짜 불러오기

let today = changeDateForm(new Date());
let yesterday = changeDateForm(new Date(new Date().setDate(new Date().getDate()-1)));
let twodaysago = changeDateForm(new Date(new Date().setDate(new Date().getDate()-2)));

...

if (uniqueDate[i] === today) {
  strong_date.textContent = "오늘";
} else if(uniqueDate[i] === yesterday) {
  strong_date.textContent = "어제";
} else if(uniqueDate[i] === twodaysago) {
    strong_date.textContent = "2일전";
} else {
    strong_date.textContent = uniqueDate[i];
}


만약, 클라이언트 요구사항이 바뀌어 2일전이 아니라 n일전까지 만들어달라고 하면 n개의 변수를 만들 수는 없다. 그래서 리팩토링을 진행하였다. (ex. num=5라면, 오늘, 어제, 2일전, ... , 5일전 형식으로 출력되고, 그 이후로는 날짜로 출력된다.)

let num = 3;
let now = new Date();
let today= `${now.getFullYear()}.${now.getMonth()+1}.${now.getDate()}`;

...

if (i === idx) {
  strong_date.textContent = "오늘";
  cnt++;
} else if (i === idx + 1) {
  strong_date.textContent = "어제";
  cnt++;
} else if (i < (idx + num + 1)) {
  strong_date.textContent = `${cnt}일전`;
  cnt++;
} else strong_date.textContent = uniqueDate[i];

🤔 같은 기능을 하는 코드, 어떤 코드가 더 효율적일까?
1번과 2번은 같은 결과가 변수에 담기게 된다.
사실 성향 차이이긴 하지만.. 처음에 1번 코드로 작성했는데, 알아보기도 어렵고 너무 조잡한 코드인 것 같아서 2번으로 변경하게 되었다. 그리고 실제로도 1번보다 2번이 더 효율적이다. replacefilter처럼 반복을 하는 것이라 실행이 더 오래 걸린다.

// 1
let today = ((new Date().toLocaleDateString()).replace(/(\s*)/g, "")).slice(0, -1);
// 2
let now = new Date();
let today2= `${now.getFullYear()}.${now.getMonth()+1}.${now.getDate()}`;

지출 합계 계산

if-else 부분에서 else 부분과 if (elem.inOut == 'out') 부분이 같은 조건이므로 코드를 간소화했다.

if(elem.inOut == "in") {
  span_price.textContent = `+ ${priceToString(elem.price)}`;
  span_price.style.cssText = "color: #FF5F00";
}
else {
  span_price.textContent = priceToString(elem.price);
  sum += elem.price;
}
...

if (elem.inOut == 'out')
  sum += elem.price;

if(elem.inOut == "in") {
  span_price.textContent = `+ ${priceToString(elem.price)}`;
  span_price.style.cssText = "color: #FF5F00";
}
else {
  span_price.textContent = priceToString(elem.price);
  sum += elem.price;
}

불필요한 코드 삭제

처음에 사용했던 JSON 파일에서 가격이 없어 출력 시 에러가 나는 것을 방지하기 위해 인자를 검사하는 코드를 넣었는데, 현재 사용하고 있는 JSON 파일에는 모두 가격이 적혀있어 해당 코드(if(price === null) return;)를 삭제했다.

function priceToString(price) {
  if(price === null) return;
  return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};

함수 선언 위치 변경

함수는 사용하기 이전에 선언하는 것이 좋다.

profile
🙋‍♀️

0개의 댓글