본문 바로가기
Algorithm

[Algorithm] JSON.stringify 메소드 구현하기

by 개발자 염상진 2022. 5. 13.

 

JSON은 네트워크에서 메시지를 전송할 때 사용하는 포맷이다. JSON은 트리 자료구조 형식을 가지고 있기 때문에 전송할 때는 Object를 String으로 변환해주어야 하고, 수신자는 String을 다시 Object로 변환해서 사용해야 한다. 

 

JSON이란?

 

[Programming] JSON 이란?

JSON 이란? JSON(JavaScript Object Notation)은 데이터 포맷의 한 형식이다. 네트워크에서 다른 사용자에게 데이터를 전송할 때 특정 포맷을 사용해야 하는데, 이 중 XML, JSON 등의 포맷이 존재한다. 네트워

about-tech.tistory.com

 

이번에는 JSON에서 제공하는 stringify() 메소드를 직접 구현해본다.

JSON.stringify() 구현하기

 

stringify() 메소드는 제약조건을 가지고 있다.

① JSON은 funtion과 undefined는 지원하지 않는다.

② 문자열은 "string" 형태로 반환해야 한다.

③ 숫자는 number 형태로 반환한다.

④ 배열은 [number, "string", true] 형식으로 반환한다.

 

풀이 : 

obj를 매개변수로 받은 stringifyFunction()은 obj를 반환한다.

입력받는 값의 타입은 null, undefined, function, object, array, string, number 을 기준으로 한다.

 

가장 먼저 임의의 obj를 생성한다.

let newObj = '';

 

첫번째 필터 조건으로 null을 입력받은 경우 로직을 구성한다. null을 최상단으로 올린 이유는 하위에 조건이 존재할 경우 다른 조건문에 걸리기 때문이다. 

if(obj === null){
	newObj += `${obj}`;
}

 

 

두번째로 배열을 입력받은 경우 로직을 구성한다.

① 배열은 '['과 ']'로 구성된다.

② 배열 내의 요소 중간에는 ','이 삽입되어야 하고 마지막에는 생략한다. 이를 위해 Object에서 마지막 key값을 추출하여 현재 배열과 비교하는 작업을 거친다. 마지막 요소는 일치하기 때문에 ',' 가 삽입되지 않는다.

③ 배열의 요소들을 출력할 때도 number, boolean, null, string이 포함되어 있기 때문에 stringifyFunction()을 재귀호출한다. 배열의 요소들을 순회하면서 재귀 로직을 통해 배열내에 각 타입에 맞는 적합한 요소들을 출력할 수 있다.

else if(Array.isArray(obj)){
    newObj +=`[`;
    for(let el in obj){
      newObj +=`${stringifyJSON(obj[el])}`;
      const last = Object.keys(obj).pop();
      if(el !== last ) newObj += ',';
    }
    newObj +=`]`;
}

 

세번째로 Object를 매개변수로 받은 경우 로직을 구성한다.

① Object는 { 과 } 로 감싸져 있기 때문에 먼저 기호를 삽입한다.

② undefined와 function인 경우 반환할 리턴값을 String으로 강제 변환시킨다. JSON에서는 undefined와 function은 지원하지 않는다.

 

null이나 undefined가 존재하는 Object를 Object.keys(object)로 읽어들일 경우 에러가 발생한다.

에러 :  TypeError: Cannot convert undefined or null to object

해결방법은 undefined와 null인 경우 Object를 call 하지 않는 로직을 만들어줘야 한다. 즉, 타입이 null이나 undefined인지 확인 한 후 예외 로직을 구성한다.

 

③ Object의 value 값을 매개변수로 해서 재귀함수를 돌린다. 다른 하위 Object가 없을 때 까지 진행되고 Object 마지막에는 ',' 기호를 생략한다.

else if(typeof(obj) === 'object'){
    newObj += '{'

    for(const key in obj){
      if(obj[key] === undefined || typeof(obj[key])==='function'){
        newObj = String(newObj);
      }else{
        newObj += `"${key}":${stringifyJSON(obj[key])}`;
        const last = Object.keys(obj).pop();
        if(key !== last && obj !== '{}'){
          newObj += ',';
        }
      }
    }

  newObj += '}';
  }

 

네번째로 ooolean, number, string에 대한 로직을 구성한다.

boolean과 number는 추가적인 기호 없이 반환한다.

string은 ""로 감싸주고 반환한다.

else if(typeof(obj) === 'boolean'){
	newObj += `${obj}`;
}


else if(typeof(obj) === 'number') {
	newObj += `${obj}`;
}

else if(typeof(obj) ==='string'){
	newObj += `"${obj}"`;
}

 

소스코드 : 

function stringifyFunction(obj) {

  let newObj = '';
  
  
  if(obj === null){
    newObj += `${obj}`;
  }
  
  else if(Array.isArray(obj)){
    newObj +=`[`;
    for(let el in obj){
      newObj +=`${stringifyJSON(obj[el])}`;
      const last = Object.keys(obj).pop();
      if(el !== last ) newObj += ',';
    }
    newObj +=`]`;
  }

  else if(typeof(obj) === 'object'){
    newObj += '{'

    for(const key in obj){
      if(obj[key] === undefined || typeof(obj[key])==='function'){
        newObj = String(newObj);
      }else{
        newObj += `"${key}":${stringifyJSON(obj[key])}`;
        const last = Object.keys(obj).pop();
        if(key !== last && obj !== '{}'){
          newObj += ',';
        }
      }
    }

  newObj += '}';
  }

  else if(typeof(obj) === 'boolean'){
    newObj += `${obj}`;
  }

  
  else if(typeof(obj) === 'number') {
    newObj += `${obj}`;
    

  }
  else if(typeof(obj) ==='string'){
    newObj += `"${obj}"`;
  }
  
  return newObj;
  
};

 

 

JSON.stringify() 구현하기 정리

 

JSON은 undefined와 function 타입을 지원하지 않는다.

Object는 기본적으로 트리구조를 가지고 있기 때문에 재귀 함수를 사용하기에 적합하다.

JSON은 키와 밸류 모두 큰 따옴표로 감싸줘야 한다.

댓글