본문 바로가기
javascript/javascript

자바스크립트 JSON.parse(), JSON.stringify() 함수의 특징과 활용

by 산코디 2023. 1. 16.

자바스크립트 JSON.parse(), JSON.stringify() 함수의 특징과 활용

오늘은 자바스크립트에서 서버와 클라이언트 간 데이터 통신을 하다 보면 많이 사용하게 되는 JSON.parse()와 JSON.stringify() 기능에 대해 정리해 봤다. 기능 이름에서는 JSON이라고 되어 있어서 JSON 유형의 값만 해당되진 않지만 보통은 JSON 데이터를 처리할 때 많이 사용을 한다. 물론 일반적인 유형의 데이터를 처리할 때에도 사용을 한다.
그럼 두 종류의 함수에 대해서 하나씩 살펴보도록 하자.

 


JSON.stringify() 함수의 개념과 특징

JSON.stringify() 함수는 자바스크립트의 객체나 값을 JSON 문자열로 변환하는 함수다. 자바스크립트의 객체를 문자열 형태로 변환할 수 있어서 네트워크를 통해 데이터를 주고받거나 데이터를 저장할 때 유용하게 사용된다.

객체는 문자열로 변환 (JSON -> string)
JSON.stringify() 함수는 자바스크립트의 객체나 배열 등을 문자열 형태로 변환한다. 

중첩 객체 변환
JSON.stringify() 함수는 중첩된 객체도 재귀적으로 문자열로 변환한다. 즉, 객체 내에 또 다른 객체가 있어도 이를 모두 문자열로 변환한다.

데이터 손실 없음
JSON.stringify() 함수를 통해 JSON으로 변환된 데이터는 데이터의 손실 없이 JSON 형식을 따르게 되는데, 변환된 JSON 데이터를 다시 자바스크립트 객체로 파싱하면 원본 데이터를 얻을 수 있다.

매개변수
JSON.stringify() 함수에는 두 가지 매개변수가 있는데, 첫 번째는 replacer 함수로, 반환할 값을 조정하기 위해 사용되며, 두 번째는 space 매개변수로 들여쓰기를 추가하여 출력 결과를 보기 좋게 만들 수 있다.

순환 참조 처리
JSON.stringify() 함수는 기본적으로 순환 참조를 다룰 수 없다. 객체가 자기 자신을 참조하거나 상위 수준의 객체가 하위 수준의 객체를 참조하는 경우, JSON.stringify()는 에러를 발생시킨다. 이를 해결하기 위해서 replacer 함수를 사용하여 순환 참조를 처리할 수 있다.
replacer 함수를 사용하면 순환 참조된 객체나 프로퍼티를 무시하거나 대체할 수 있다.

날짜 객체 처리
JSON.stringify() 함수는 날짜 객체를 JSON 문자열로 변환할 때 특별한 처리를 하지 않는다. 따라서 날짜 객체를 JSON 문자열로 변환하면 해당 객체가 문자열로 변환되어 저장된다. 날짜 객체의 함수나 프로퍼티가 유실될 수 있으며, 이를 해결하기 위해서는 replacer 함수를 사용하여 날짜 객체를 사용자 정의 형식으로 변환할 수 있다.


위와 같은 특징들은 JSON.stringify() 함수를 사용할 때 고려할 부분들이며, 특히 순환 참조나 특수한 데이터 타입을 다루어야 하는 경우에는 이러한 특징들을 고려하여 적절한 처리를 하는 것이 중요하다.


JSON.stringify() 기본 예제

<script>
// JSON 형태의 데이터
const dataObj = {
    "name": "test", 
    "list" : ["a", "b", "c", "d", "e"]
};

// JSON.stringify() 처리
const dataStr = JSON.stringify(dataObj);

console.log(dataObj);    
console.log(dataStr);
</script>

위의 코드는 dataObj라는 심플한 JSON 구조의 데이터를 만들고 JSON.stringify() 함수를 사용하여 문자열로 변환하는 간단한 예제 코드다.

위의 결과와 같이 원본 데이터는 JSON 구조 형태로 찍히고, stringify 처리를 한 데이터는 string 문자열로 처리가 잘 된 것을 확인할 수 있다.


JSON.stringify() 매개변수 replacer

// 객체 정의
const person = {
  name: 'John',
  age: 30,
  city: 'New York'
};

// replacer를 사용하여 age 속성을 필터링
const jsonString = JSON.stringify(person, (key, value) => {
  // age 속성 필터링
  if (key === 'age') {
    return undefined; // age 속성 제외
  }
  return value; // 다른 속성은 그대로 반환
});

// 결과 출력
console.log(jsonString);

위의 코드는 JSON.stringify() 함수를 사용할 때 첫 번째 매개변수로 replacer 함수 처리가 가능하다. 
person이라는 개인정보 JSON 객체를 기준으로 문자열 변환을 하려고 할 때 위와 같이 익명함수를 사용해 person 정보를 가공한 후 문자열로 변환을 하게 된다. replacer 함수 처리할 때 key가 age인 항목은 제외 후 나머지만 반환하여 문자열로 변환한다.

{"name":"John","city":"New York"}

위의 코드를 실행하면 위와 같이 age 항목만 제외된 후 결괏값을 얻을 수 있다.


JSON.stringify() 매개변수 space

// 객체 정의
const person = {
  name: 'John',
  age: 30,
  city: 'New York'
};

// space를 사용하여 들여쓰기 적용
const jsonString = JSON.stringify(person, null, 2);

// 결과 출력
console.log(jsonString);

위의 코드는 JSON.stringify() 함수의 두 번째 매개변수로 space 처리가 가능하다. space는 변환하고자 하는 JSON 객체 내의 요소 들여 쓰기를 하는 것인데, 지정한 space 값만큼 JSON 객체 내의 요소가 들여 쓰기가 되고 그 후 문자열로 변환하게 된다.

'{\n "name": "John",\n "age": 30,\n "city": "New York"\n}'

위의 결과와 같이 각 요소마다 들여쓰기 2칸씩 처리된 것을 확인할 수 있다.


이렇게 JSON.stringify() 함수의 매개변수까지 적절히 잘 활용한다면 JSON 객체를 적절히 가공한 후 문자열로 변환할 수 있다.


JSON.parse() 함수의 개념과 특징

JSON.parse() 함수는 JSON 형식의 문자열을 읽어 들여 자바스크립트의 데이터 타입으로 변환한다. 이를 통해 서버로부터 받은 JSON 데이터를 자바스크립트에서 활용할 수 있다.


문자열 파싱

JSON.parse() 함수는 JSON 형식의 문자열을 파싱하여 자바스크립트 객체로 변환한다. 이를 통해 문자열 형태의 JSON 데이터를 자바스크립트에서 객체로 사용할 수 있다.

문자열 유효성 검사
JSON.parse() 함수는 입력된 문자열이 유효한 JSON 형식인지 검사한다. 유효하지 않은 JSON 문자열이 입력되면 에러가 발생한다.

Reviver 함수
JSON.parse() 함수는 두 번째 매개변수로 reviver 함수를 받을 수 있으며, 이 reviver 함수를 사용하면 파싱된 결과를 재귀적으로 수정할 수 있다. 이를 통해서 데이터를 파싱하면서 원하는 형태로 변환할 수 있다.

JSON 데이터 유형
JSON.parse() 함수는 JSON 데이터의 유형에 따라 적절한 자바스크립트 데이터 타입으로 변환한다. 예를 들어, 숫자는 자바스크립트의 숫자로, 문자열은 자바스크립트의 문자열로 변환된다.

순환 참조 처리
JSON.parse() 함수는 순환 참조를 포함하는 JSON 데이터를 처리할 수 있다. 순환 참조는 객체나 배열 내부에서 자기 자신을 참조하는 경우를 말하는데, 이러한 경우에도 JSON.parse() 함수는 순환 참조를 올바르게 처리하여 객체나 배열을 생성한다.


JSON.parse() 기본 예제

<script>
// string 형태의 JSON 데이터
const dataStr = '{ "name": "test", "list" : ["a", "b", "c", "d", "e"] }';

// JSON.parse() 처리
const dataObj = JSON.parse(dataStr);

console.log(dataStr);
console.log(dataObj);
</script>

위의 코드는 문자열로 변환된 JSON 데이터를 다시 JSON으로 바꿀 수 있도록 JSON.parse() 함수를 사용한 기본 예제 코드다.
원본 데이터는 JSON 구조이며, 전체는 홀따옴표(')로 감싸줬다.
파싱하고자 하는 데이터가 JSON 유형이 아닌 경우는 에러가 발생할 수 있으니 반드시 예외처리를 해줘야 한다.

stringify 처리를 해서 만들었던 string 데이터에 JSON.parse 처리를 해줬더니 원래의 JSON 구조 데이터로 돌아온 결과를 확인할 수 있다.


JSON.parse() 매개변수 reviver

const jsonString = '{"name":"John","age":30,"date":"2024-04-25"}';

const reviver = (key, value) => {
  // 'date' 키에 해당하는 값이 문자열인 경우 Date 객체로 변환
  if (key === 'date' && typeof value === 'string') {
    return new Date(value);
  }
  return value;
};

const parsedObject = JSON.parse(jsonString, reviver);
console.log(parsedObject);

위의 코드는 JSON 구조의 문자열 데이터를 기준으로 JSON.parse() 함수를 사용할 때 매개변수로 reviver 함수를 활용해 처리하는 예제 코드다.
reviver 함수를 사용하게 되면 문자열을 파싱한 후 결과 데이터를 반환하기 전에 JSON 객체를 원하는 형태로 가공한 후 최종적으로 반환하게 되는 기능이다. 함수 내용을 살펴보면 date에 해당하는 요소의 값을 날짜 데이터로 간주하고 new Date()로 변환시켜주고 있다.

{
    name : 'John',
    age : 30,
    date : Wed Apr 24 2024 17:00:00 GMT-0700 (북미 태평양 하계 표준시)
}

실행 결과는 위와 같이 정상적으로 JSON 형태로 변환되었고, reviver 함수를 통해 date 요소만 Date 형태로 변경되었다.


원본 데이터를 그대로 파싱해야 하는 경우라면 해당 매개변수는 사용하지 않아도 되지만, 특정 상황에 파싱 후 원본 데이터를 가공해야 하는 경우라면 유용하게 활용될 수 있다.

반응형

데이터 유형별 JSON.stringify() & JSON.parse() 처리

JSON 형태의 데이터가 아니더라도 JSON.stringify()와 JSON.parse() 함수는 데이터 유형별로 다양하게 처리될 수 있다.

배열 유형

// 배열
const arr = ["a", "b", "c", "d", "e"];
const arrString = JSON.stringify(arr);
const arrParse = JSON.parse(arrString);

console.log('* 베열 유형');
console.log(arr);
console.log(arrString);
console.log(arrParse);

위의 코드는 배열 형태의 데이터를 JSON.stringify()로 문자열 변환을 하고, JSON.parse()로 다시 원복하는 예제 코드다.


배열 유형 데이터의 JSON.stringify() 처리와 JSON.parse() 처리 결과를 확인할 수 있다.


문자열 유형

// 문자열
const str = 'abc';
const strString = JSON.stringify(str);
const strParse = JSON.parse(strString);

console.log('* 문자열 유형');
console.log(str);
console.log(strString);
console.log(strParse);

위의 코드는 일반 문자열 데이터를 JSON.stringify() 함수를 써서 변환하고, 다시 JSON.parse() 함수를 써서 원복하는 예제 코드다.

결과는 배열 데이터와 동일하게 정상적으로 처리된다.


숫자 유형

// 숫자
const num = 123;
const numString = JSON.stringify(num);
const numParse = JSON.parse(numString);

console.log('* 숫자 유형');
console.log(num);
console.log(numString);
console.log(numParse);

숫자형 데이터도 역시 동일하게 문자열 변형과 원복 처리가 가능하다.

숫자 유형 데이터의 JSON.stringify() 처리와 JSON.parse() 처리 결과를 확인할 수 있다.


boolean 유형

// boolean
const bool = true;
const boolString = JSON.stringify(bool);
const boolParse = JSON.parse(bool);

console.log('* boolean 유형');
console.log(bool);
console.log(boolString);
console.log(boolParse);

boolean 유형의 데이터도 역시 가능하다.

boolean 유형 데이터의 JSON.stringify() 처리와 JSON.parse() 처리 결과를 확인할 수 있다.


JSON 변환시 주의사항

JSON.stringify() 함수와 JSON.parse() 함수를 사용할 때 주의해야 할 사항이 몇 가지 있다.


순환 참조
JSON.stringify() 함수는 객체를 JSON 문자열로 직렬화할 때 순환 참조가 있는 경우에는 오류를 발생시킨다. 순환 참조는 객체가 서로를 참조하는 경우를 의미한다. 이런 경우에는 직렬화할 수 없으므로 오류가 발생하게 된다.

날짜 객체
JSON.stringify() 함수로 날짜 객체를 직렬화할 때에는 기본적으로 ISO 형식의 문자열로 변환된다. 하지만 날짜 객체의 모든 정보를 유지하지 않으므로 주의가 필요하며, 날짜 객체를 직렬화할 때에는 직접 형식을 지정하거나, replacer 함수를 사용하여 처리할 필요가 있다.

함수와 심볼
JSON.stringify() 함수로 함수나 심볼 값을 직렬화할 때에는 무시된다. 이는 JSON에서 함수나 심볼을 지원하지 않기 때문이다. 그래서 이러한 값을 직렬화할 필요가 없는 경우에는 제외시키는 것이 좋다.

프로퍼티의 순서
JSON.stringify() 함수로 객체를 직렬화할 때, 프로퍼티의 순서가 보장되지 않는다. JSON 표준에서 객체의 순서를 보장하지 않기 때문인데, JSON.stringify() 함수를 사용하여 직렬화한 JSON 문자열의 프로퍼티 순서에 의존해서는 안 된다.

보안
JSON.parse() 함수를 사용하여 JSON 문자열을 파싱할 때에는 주의해야 한다. JSON.parse() 함수는 문자열을 자바스크립트 객체로 변환하기 때문에, 악의적인 JSON 문자열이 주입될 경우 보안 문제가 발생할 수 있으며, 신뢰할 수 없는 원본에서 받은 JSON 문자열을 파싱할 때에는 반드시 안전하게 검증을 해야 한다.

취약점
JSON.parse() 함수에 대한 취약점을 방어하기 위해, reviver 함수를 사용하여 파싱된 객체를 검사하고 필요한 경우 값의 변환 또는 거부를 할 수 있다. reviver 함수를 사용하여 신뢰할 수 없는 JSON 문자열을 안전하게 파싱할 수 있다.


위의 정리한 바와 같이 주의사항을 염두에 두고 두 함수를 활용한다면 효율적으로 JSON 데이터를 처리할 수 있다.


마무리

오늘은 이렇게 자바스크립트의 JSON.stringify()와 JSON.parse() 기능과 특징에 대해 살펴봤다.
두 함수의 사용법은 간단하지만, 변환하고자 하는 데이터의 유형이 JSON이 맞는지 확인하는 것이 중요하고, JSON.parse() 함수를 통해 다시 원복 처리할 때 이미 JSON 형태인데 중복으로 호출되는 것은 아닌지 등 신경써야 할 부분들이 있다.
그럼에도 함수의 활용성은 강력하기 때문에 업무에서 필요한 경우에는 꼭 활용해 보는 것을 추천한다.

반응형