본문 바로가기
개발자 일기/일일회고 (TIL)

부트캠프 42일차 (JSON.stringify)

by MS_developer 2022. 10. 21.

영화 '스파이더 맨: 노웨이홈'

오늘의 생각

꽤 익숙했던 JSON.stringify / JSON.parse 에 대해 더 잘 알게되었다.

 

이미 알고 있던 코드와 역할이었기 때문에 문법적으로 어렵지 않아서 배울 때는 꽤 여유로웠다. 특히 stringify의 개념에 대해 더 자세히 알게 됐고, 관련용어를 배워서 누군가에게 설명하기 더 수월해진 것 같다.

 

오늘 일과의 대부분은 JSON.stringify를 구현하는 과제와 재귀를 활용해 Tree UI를 구현하는 것이었다.

 

진행 중에 어려웠던 부분들이 제법 있었는데, 특히 객체 안의 객체를 다루는 부분이 많이 어려웠다.

 

function stringifyJSON(obj) {
  let str = "";
  for (prop in obj) {
    if (typeof obj[prop] === "string") {
      str += `"${prop}":"${obj[prop]}",`;
    } else {
      // 의도: 해당 속성의 값이 문자열이 아닐 경우. (배열 객체 포함)
      str += `"${prop}":${obj[prop]},`;
    }
  }
  return str;
}

 

기본적으로 사용했던 방법은 탬플릿 리터럴template literal을 활용해 객체에 해당하는 키와 값을 리턴할 문자열에 이어붙이는(concat)의 방법을 사용했다. 이를 통해 키key와 값value에 해당하는 요소들을 stringify하는 한편, 키와 연결된 값이 문자열일 경우 해당 값에는 따옴표("")로 감싸줄 수 있도록 코드를 작성했다.

 

문제는 순회마다 쉼표(,)를 넣어 각 키-값 쌍을 분류해줄 수 있어야 했다. 

 

obj.forEach(function (i, index) {
      str += stringifyJSON(i);
      if (index !== obj.length - 1) {
        str += ",";
      }
    });

 

기존에 전달받는 객체 안의 요소가 데이터일 경우 배열이 갖는 특성 index를 활용해 배열의 마지막 요소를 제외한 각 요소들 사이에 쉼표를 추가했다. 하지만 객체는 배열의 특성, 정리된 번호(index)가 할당되어있지 않기 때문에 순회할 때 현재 객체에서 마지막 요소를 다루고 있는지 없는지 알기 힘들었다.

 

 

처음에는 str.slice(0,-1)를 사용해 최종적으로 문자열을 반환하기 전에 반복해서 요소 뒤에 추가한 마지막 쉼표(,)를 삭제하려고 해 보았다. 하지만 이럴 경우 객체가 마지막 요소에 접근했을 때 해당 문자열 { b:c } 의 마지막 요소 } 가 먼저 삭제되었다.

 

// 생략
for (prop in obj) {
  let str = "";
  let count = 0;
  let keyList = Object.keys(obj); // 객체에 해당하는 키의 배열

  // 생략

  if (count !== keyList.length - 1) {
    str += ",";
  }

  count++;
}

 

이에 따라 기존에 사용했던 배열의 방법을 참고해 객체의 마지막 요소에 도달했을 때를 판단한 후 해당 경우에만 쉼표를 추가하지 않는 방법을 찾아냈다. 먼저 객체가 가지고 있는 키를 모아놓은 배열을 만든 후, count 변수를 통해 객체를 순회할 때마다 1씩 증가시켰다. 이후에는 기존 배열에서 체택했던 방식을 그대로 구현했다. 

 

 

결과는 성공이었다. 뿌듯

 

Tree UI 구축은 이보다 더 수월했는데, 먼저 함께한 페어분과 함께 의논하며 필요로 하는 구조를 생각한 후, 이를 의사 코드로 작성해 보았다. 

 

  // Pseudo::
  // base case: 가장 하위에 있는 노드; type: 'item'이고, name이 span으로 감싸지 않는다.
  // recursive case: type: 'group', children 속성이 있는 경우

  // Node Structure
  // 객체 본인: <li> -> 여는 태그

  // <Case 1>
  // type: 'group', children 속성이 있고, 같이 있는 경우
  // 첫번째 자식: <input type="checkbox">
  // 두번째 자식: <span> obj.name </span>
  // 세번째 자식: <ul/> => 재귀 함수 호출

  // <Case 2>
  // type: 'item', children 속성이 없는 경우
  // li 태그 생성
  // li.textContent = obj.name;

  // </li> -> 닫는 태그

 

이후에는 코드를 받아 적는 기분으로 문제없이 구현했다. 

 

이제는 재귀에 제법 익숙해진 것 같아 기분이 좋은 하루였다.


오늘의 키워드

JSON, JSON.stringify, JSON.parse

 


오늘의 학습내용

  • JSON의 정의와 사용하는 이유
  • JSON.stringify와 JSON.parse의 사용법과 변환 방식
  • 자바스크립트 객체와 JSON의 차이점

 


어려웠던 keyword / 활용한 질문

 

Q. 자바스크립트 객체와 JSON이 다른 이유 중 하나인 "범용성"에 대해서 설명해 주세요.

 

A. JSON은 서로 다른 프로그램 사이에서 데이터를 교환하기 위한 포맷이기 때문에 자바스크립트는 포함한 많은 언어에서 범용적으로 사용할 수 있습니다. 

 

Q. 왜 JSON 구조가 재귀 함수를 사용할 수 있는 구조인가요?

 

A.  JSON 구조는 객체 안에 객체, 객체 안에 배열 등 다양한 자료 구조를 포함하고 있을 수 있기 때문에 트리 구조 안의 모든 노드Node를 확인하기 위해 재귀 함수를 사용해야 합니다. 이는 즉, JSON 구조를 순회할 때 중첩횟수를 예측하기 어렵기 때문에 재귀 함수를 사용하는 것이 적절합니다.

댓글