JSON 에 관하여

조 은길·2021년 3월 16일
10

Javascript 정리

목록 보기
1/48
post-thumbnail

이번 시간에는 JSON 객체에 관하여 알아보자!!

JSON은 쉽다면, 쉽지만 매우 강력한 tool이기 때문에 한 번쯤 정리하고 넘어갈 필요가 있다.

1. JSON 탄생 배경

JSON(JavaScript Object Notation)은 데이터 교환을 위해 만들어진 포맷이다. 개발자가 만일 어떤 객체 내용을 네트워크를 통해 다른 프로그램에게 전송한다고 생각해 보자. 여기서는 일종의 메신저 혹은 채팅 프로그램에서 쓰는 하나의 메시지라고 간주해보자. 다음 객체를 어떻게 보낼 수 있을까?

const message = {
  sender: "조코딩",
  receiver: "감초보",
  message: "초보야 오늘 저녁 같이 먹을래?",
  createdAt: "2021-01-12 10:10:10"
}

객체라는 것이 전송 가능(transferable)하려면 애초에 수신자(reciever), 발신자(sender) 모두가 같은 프로그램을 쓰거나, 아니면 문자열과 같이 범용적으로 읽을 수 있는 형태여야만 할 것이다.

혹시나 싶어 엔지니어는 message.toString() 메소드나, String(message)를 시도해보았지만, 리턴되는 것은 그저 [object Object]라는 메시지 뿐이었다.

이 문제를 인지한 엔지니어는, 다른 방법을 찾기 시작했고, 객체를 문자열로 멋지게 변환하는 JSON.stringify 함수를 mdn을 통해 알아낼 수 있었다.

JSON (JavaScript Object Notation)

  • 일반적으로, 웹 어플리케이션에서 데이터를 전송할 때 많이 사용한다.
    ex) 서버에서 클라이언트로 데이터를 전송하여 표현하려거나 그 반대의 경우

참고로, 거의 모든 언어에서 JSON을 사용한다. Java, PHP, C# 등등
그러나, JSON이 JS이기 때문에, 다른 언어들은 JSON을 자기들 언어로 변환하기 위한 추가적인 작업들이 필요하다.(물론, 개발자가 일일히 할 필요는 없지만...) 그러나, Node.js는 JS 런타임이기 때문에, 이런 번거로운 작업 필요없다.

개념은 이게 끝인데... 이렇게만 알면 뭔가 부족하니 JSON의 중요한 특징에 대해 몇 가지 알아보자!! 하지만, 특징 같은 거 몰라도 코딩하는데 전혀 상관 없다.


JSON의 특징 (optional)

  • 데이터를 주고 받을 때, 쓸 수 있는 가장 간단한 포맷

  • C++이나 JAVA 등 대부분의 프로그래밍 언어에서 JSON 포맷을 지원한다.

  • JSON은 데이터 포맷일 뿐이며 어떠한 통신 방법도, 프로그래밍 문법도 아닌 단순히 데이터를 표시하는 표현 방법일 뿐이다.

  • JSON 문서 형식은 자바스크립트 객체의 형식을 기반으로 만들어졌다.

  • 자바스크립트의 문법과 굉장히 유사하지만, 텍스트 형식일 뿐이다.

  • 서버와 클라이언트 간의 교류에서 일반적으로 많이 사용된다.

  • 과거에는 데이터를 포맷할 수 있는 방식 중에 XML이 지배적이었지만, 요즘은 JSON도 거의 비슷한 사용 횟수를 보이고 있다.


[TMI] JSON vs XML (optional)

a. XML은 오래되고 여전히 광범위하게 사용되지만, 적어도 웹 API 관련해서는 점차 외면당하고 있는 현실이다.

b. XML을 사용하면, 불필요한 테그들이 너무 많이 들어가서, 거기에 따른 가독성도 않좋다.

c. XML은 테그가 많아짐에 따른 불필요한 메모리 문제도 발생한다. 그런 이유로, 요즘은 JSON을 더 선호한다.

d. XML은 배열(Array)을 사용할 수 없지만, JSON은 배열을 사용할 수 있다.

좀 더 자세한 내용이 궁금하다면, 이 링크를 따라가면 된다.


JSON 문법

  • JSON 형식은 자바스크립트 객체와 마찬가지로 key / value가 존재할 수 있으며 key값이나 문자열은 항상 쌍따옴표를 이용하여 표기해야한다.

  • 객체, 배열 등의 표기를 사용할 수 있다.

  • 일반 자바스크립트의 객체처럼 원하는 만큼 중첩시켜서 사용할 수도 있다.

  • JSON형식에서는 null, number, string, array, object, boolean을 사용할 수 있다.

  • 단!! function은 object에 있는 Data가 아니기 때문에 변환되지 않고 사라진다. 이 부분은 밑의 예시에서 좀 더 확인해 보자!

JSON 규칙

JSON은 얼핏 보기에 자바스크립트의 객체와 별반 다를 바가 없어 보이지만, 자바스크립트의 객체와는 미묘하게 다른 규칙이 있다.

자바스크립트 객체JSON
키는 따옴표 없이 쓸 수 있음반드시 쌍따옴표를 붙여야 함
문자열 값문자열 값은 어떠한 형태의 따옴표도 사용 가능반드시 쌍따옴표로 감싸야 함

또한 JSON은 키와 값 사이, 그리고 키-값 쌍 사이에는 공백이 있어서는 안된다.

JSON 메소드

  • 밑에서 나온 예시들은 " 드림 코딩의 엘리님 "의 예시 중 일부를 가져왔다.
    내가 만든 예시들보다 훨씬 잘 만들어 주셨다.

> 1. JSON.stringify() – 객체를 JSON으로 바꿔줍니다

stringify하는 이 과정을 직렬화(serialize)한다고 한다.

지금부터는 rabbit 이라는 객체를 이용해서 JSON을 실험해보자!! 밑에 이어지는 JSON.parse( ) 부분까지 계속 쓸 예정이니 직접 따라해보는 것도 좋은 학습법인 것같다.

const rabbit = {
  name: 'tori',
  color: 'white',
  size: null,
  birthDate: new Date(),
  jump: () => {
	console.log( `${name} can jump!` );
	},
};

위와 같이, json = JSON.stringify(rabbit); 이후 JSON 값을 출력해보면

모두 큰 따옴표( " " )가 쳐져서 변환 된 것을 확인할 수 있다!!

JSON 객체의 문제점

그런데, 이 JSON 객체에는 2가지 문제점이 있다.

1. 객체가 value 값으로 가지고 있던 jump( )는 JSON 객체로 변환되지 않았다.

=> 즉, 변환된 JSON 파일에서 jump( )를 찾아봐야 undefined만 뜬다.
그리고, 함수가 사라진 rabbit이라는 JSON 객체를 다시 원래의 자바스크립트 객체로 바꿔준다고 해도 jump( )는 되돌아오지 않는다!!

2. birthDate 안의 new Date( ) 값이 문자열로 출력이 됐다.

=> 다시 말해서, rabbit이라는 JSON 객체를 다시 원래의 JS 객체로 바꿔줘도 birthDate: new Date() 라는 메소드로 되돌아오는 것이 아니라 "2020-05-29T13...." 같은 문자열 형태로 반환된다. 다시 말해서, new Date( )로부터 마지막으로 받아온 시간대가 문자열로 남아있는 것이다.

** 함수 혹은 메소드를 포함해서 자바스크립트에만 있는 특별한 데이터도 JSON으로 변환 시에 포함되지 않는다!! ex) Symbol("id")

TMI => Symbol에 관한 더 자세한 내용


추가적으로 객체의 특정 부분만을 JSON 형태로 바꿔주고 싶다면, 이런 식으로 원하는 키 값만 넣어줘서 변환시킬 수 있다.

json = JSON.stringify( rabbit, ['name'] );

json = JSON.stringify( rabbit, ['name', 'color', 'size'] );


좀 더 응용을 해보자면, 이런 것도 가능하다.

( 개인적으로 꽤 많이 써먹으니, 익혀두는 것을 권장한다. )

JSON.stringify을 콜백 함수 형식으로 전달해 주고,
1) key와 value 값들을 출력해볼 수 있다.

=> 다만, 출력시에 맨 처음 나오는 부분은 rabbit이라는 JS 객체를 감싸고 있는 최상위 부분이다. 상품을 뜯기 전에 뜯어야 되는 포장지도 같이 나온다고 생각하면, 이해가 쉽다.

2) 객체 내의 특정 key와 value 대해서 컨트롤 할 수있다.

return key === 'name' ? 'ellie' : value;
=> 객체 중에, 만약에 key가 name이라면 value 값을 ellie로 바꿔주고, 다른 key가 들어온다면, value 그대로 써줘라!!

이제 name 이라는 key 값에 어떤 value가 있었던 ellie로 덮어씌워졌다.


JSON.stringify는 중첩 객체도 알아서 문자열로 바꿔준다.


> 2. JSON.parse() – JSON을 객체로 바꿔줍니다.

=> JSON으로 인코딩된 객체를 다시 객체로 디코딩 할 수 있다.

parse하는 이 과정을 역직렬화(deserialize)한다고 한다.
이처럼, JSON은 서로 다른 프로그램 사이에서 데이터를 교환하기 위한 포맷이며, 단순히 자바스크립트에서만 쓰이는 것이 아닌, 여타 다른 언어에서도 범용적으로 쓰이는 아주 유명한 포맷이다.

이제, 위에서 JSON으로 변환한 rabbit을 다시 JS 객체로 변환해보자!!

const obj =JSON.parse(json);

제대로 변환은 됐지만, 위에서 언급했던 문제를 다시 확인할 수 있다.

line 41 번에 obj.jump( ); 를 통해 객체 내의 해당 함수의 존재 여부를 확인해본 결과!!
=> 함수가 사라졌음을 확인 해볼 수 있다.

getDate( ) 메소드 역시 확인할 수 없다. ( 위에서 rabbit이라는 자바스크립트 객체를 JSON으로 변환시, 변환되지 못하고, 사라졌음!! ) 하지만,

=> 이렇게 마지막으로, getDate( )에서 마지막으로 받아온 시간대가 String 형태로 저장되있다.


JSON.parse(json) 역시도 콜백 함수 형식으로 전달해주므로써, 더 유용해질 수 있는데,

1. JSON 파일 내의 모든 key와 value 값 출력하기

2. JSON 파일을 JS 객체로 변환해주기 전에 추가 작업해주기

JSON을 JS 객체로 변환해주는 과정에서

return key === 'birthDate' ? new Date(value) : value;

Key가 birthDate이면, 나는 그 value안에 새로운 object인 new Date( )를 만들 꺼고, 그게 아니라면 그냥 value를 그대로 써줘라!!

이런 식으로 해서, JSON으로 변환하면서 사라진 new Date( ) 메소드를 다시 생성해줄 수도 있다.


JSON의 문제점

AJAX 는 단순히 데이터만이 아니라 JavaScript 그 자체도 전달할 수 있다. 이 말은 JSON 데이터라고 해서 받았는데... 단순 데이터가 아니라 JavaScript가 될 수도 있고, 그게 실행 될 수 있다는 것이다. ( 데이터인 줄 알고 받았는데 악성 스크립트가 될 수 있다. 즉, 보안에 취약하다. )

위와 같은 이유로 받은 내용에서 순수하게 데이터만 추출하기 위한 JSON 관련 라이브러리를 따로 사용하기도 한다.

여기까지 단순한 것같지만, 결코 단순하지 않은 JSON 편 끝!!!!!


- 자료 출처 및 참고 자료

이번 블로그는 코드스테이츠 의 강의 내용과 드림코딩 by 엘리 의 일부를 바탕으로 작성했으며, 그 어떠한 상업적 용도도 없음을 밝힌다.

profile
좋은 길로만 가는 "조은길"입니다😁

5개의 댓글

comment-user-thumbnail
2021년 3월 18일

json은 전반적으로 어마무시 하군요

1개의 답글
comment-user-thumbnail
2021년 3월 18일

콜백 부분은 신선한 내용이었습니다!~

1개의 답글
comment-user-thumbnail
2021년 5월 27일

Json을 신선하게 정리하셨네요. 잘 읽고 갑니다~

답글 달기