본문 바로가기

웹개발/javascript

자바스크립트 JSON

 

 

 

 

 

 

브라우저 위에서 동작하고 있는 웹 애플리케이션과 같은 클라이언트들이 어떻게 서버와 통신할 수 있는지를 정의한 것이 http (Hypertext Transfer Protocal) 이다. 클라이언트가 서버에 하이퍼텍스트를 요청하고 서버가 그 데이터를 응답하는 방식으로 진행이 되는데 여기서 하이퍼 텍스트는 하이퍼링크, 문서나 이미지 파일들을 모두 포함해서 말한다. 

이렇게 서버에게 데이터를 요청해서 받아올 수 있는 방법으로는 ajax를 사용하는 방법이 있다.

 

ajax는 Asynchronous JavaScript And XML 의 약자로 웹페이지에서 동적으로 서버에게 데이터를 주고받을 수 있는 기술을 의미한다. 대표적인 예로는 XHR (XMLHttpRequest)라는 오브젝트가 있다. 이것은 브라우저에서 제공하는 api 중에 하나이다.  최근에는 브라우저에 추가된 fetch api를 이용하면 간단하게 데이터를 주고받을 수 있다. 하지만  fetch api는 인터넷 익스플로러에서는 지원하지 않는다는 점을 주의해야 한다. 

 XHR은 XML을 사용하는데 이것을 사용하면 불필요한 태그들이 너무 많이 생겨서 요즘에는 JSON을 많이 사용하고 있다. 

 

 

 

 

JSON

JSON은 JavaScript Object Notation의 약자로 데이터를 서버와 주고받을 때 직렬화 (serialization) 하기 위해서 사용되며 key와 value로 이루어져 있다.  

제이슨은 데이터를 주고 받을 때 쓸 수 있는 가장 간단한 포맷이다. 텍스트를 기반으로 해서 가볍고 사람의 눈으로 읽기도 편하고(가독성이 좋고) 프로그래밍 언어나 언어가 쓰이는 플랫폼에 상관없이 거의 대부분의 언어들이 제이슨으로 직렬화된 직렬화된 오브젝트들을 그 언어의 특징에 맞게 오브젝트로 변환하고 그 언어의 오브젝트를 다시 제이슨으로 직렬화 하는 것을 지원해주거나 많이 쓰이고 있는 외부 라이브러리들을 통해 가능하게 해 준다. 

 

 

JSON에서 중요하게 알아둬야하는 점은 오브젝트를 어떻게 직렬화해서 제이슨으로 변환할지, 직렬화된 제이슨을 어떻게 오브젝트로 다시 변환할 건지 이 두 가지이다. 

 

 

 

 

stringjfy( )

 

let json = JSON.stringify(true);
console.log(json); //true

json = JSON.stringify(['apple', 'banana']);
console.log(json); //["apple","banana"]

JSON 오브젝트 안에 있는 두 가지 오브젝트 중 stringify를 사용하면 오브젝트를 JSON으로 변환이 가능하다. 

불리언 타입의 프리미티브 타입도 제이슨으로 변환이 가능하고 값도 불리언 타입으로 변환된다.

JSON은 stringify라는 함수를 두개 가지고 있는데 이 함수들은 이름은 동일하지만 어떤 파라미터를 전달하냐, 몇 개의 파라미터를 전달하냐에 따라서 각각 다른 방식으로 호출이 가능하다. 이것을 오버 로딩이라고 한다. 

stringify는 JSON으로 변환하면서 데이터를 string타입으로 만들때 좀 더 세밀하게 통제하고 싶다면 콜백 함수를 인자로 전달하면 조금 더 통제하면서 string타입으로 만들 수 있다. 

 

 또 key값에 쌍따옴표("")를 생략해도 자바스크립트에서는 마치 있는 것처럼 처리해주는 것과 다르게 큰따옴표("")를 확실히 표기해주고 infinity, null, NaN는 모두 null값으로 변환한다는 것이 특징이다. 

또 만약 배열의 value값을 undefined로 지정해주면 그 key값과 함께 모두 사라져 빈 배열만 남게 되니 주의하여 작성해주어야 한다. 세번째 파라미터에 가독성을 위한 구분자를 적어주면 구분자가 함께 추가되어 문자열로 변환된다. 

 

 

 

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

json = JSON.stringify(rabbit);
console.log(json); //{"name":"tori","color":"white","size":null,"birthDate":"2020-08-26T10:44:31.819Z"}

json = JSON.stringify(rabbit, ['name', 'color']);
console.log(json); //{"name":"tori","color":"white"}

json = JSON.stringify(rabbit, (key, value) => {
    console.log(`key: ${key}, value: ${value}`);
    return key === 'name' ? 'happy' : value;
})
console.log(json); 
//key: , value: [object Object] //key: name, value: tori //key: color, value: white 
//key: size, value: null //key: birthDate, value: 2020-08-26T10:45:30.431Z 
//key: jump, value: () => {console.log(`${name} jump!`);} 
//{"name":"happy","color":"white","size":null,"birthDate":"2020-08-26T10:45:30.431Z"}

 

오브젝트를 JSON으로 변환하면 birthDate는 Date라는 오브젝트가 string으로 변환되어 JSON타입으로 만들어지고 jump라는 함수는 제이슨에 포함되지 않는것을 확인할 수 있다. 함수는 오브젝트에 있는 데이터가 아니기 때문에 함수는 제외되고 자바스크립트에서 자체로 들어있는 심벌 같은 자바스크립트에만 있는 특별한 데이터도 제이슨에 포함되지 않는다. 데이터를 JSON으로 만들 때 이 점을 조금 유념해야한다. 

 

여기서 제이슨으로 변환되는 것을 조금 더 통제하고 싶다면 콜백 함수를 이용하면 된다. 콤마를 하고 함수형태로 전달해도 되고 배열 형태로 전달도 가능하다.

rabbit 오브젝트에서 이름만 JSON으로 만들고 싶다면 인자로 배열에 원하는 프로퍼티 이름만 넣어 전달하게 되면 해당하는 ksy와 value만 포함이 되어 나온다. 이렇게 원하는 목록을 만들어도 되고 아니면 콜백함수를 이용할 수 있다. replacer 콜백 함수는 key와 value를 전달받는다. 그러면 keyvalue에 따라 다양하게 데이터를 변경할수 있다. 

key value를 console에 띄워보면 모든 key value들이 콜백함수에 전달되는 것을 확인할 수 있는데  여기서 제일 처음으로 전달되는 것은 토끼의 오브젝트를 싸고 있는 제일 최상의 것이 되고 그 뒤부터 key value들이 전달된다. 이렇게 전달하는 데이터를 조금더 세밀하게 통제하고 싶을 때 콜백 함수를 쓸 수 있다. 

 

 

 

 

 

parse( )

json = JSON.stringify(rabbit);
let obj = JSON.parse(json);
console.log(obj); //{name: "tori", color: "white", size: null, birthDate: "2020-08-26T13:43:54.038Z"}
rabbit.jump(); // jump!
obj.jump();                 //Uncaught TypeError: obj.jump is not a function

console.log(rabbit.birthDate.getDate()); //26
console.log(obj.birthDate.getDate());           //Uncaught TypeError: obj.birthDate.getDate is not a function

obj = JSON.parse(json, (key, value) => {
    return key === 'birthDate' ? new Date(value) : value;
});

console.log(obj.birthDate.getDate());   //26

 

JSON.parse() 는 변환하고 싶은 JSON을 전달해주기만 하면 오브젝트로 반환해준다. 

여기서 중요한 점은 위에서 rabbit은 jump라는 함수를 포함하고 있었지만 변환한 오브젝트는 직렬 화가 된 즉 string으로 만들어진 JSON으로부터 다시 오브젝트를 만들었기 때문에 함수는 직렬화될 때 포함이 되어있지 않았다. 그래서 다시 JSON으로부터 오브젝트를 만든것에는 jump라는 api가 없어서 이것을 출력하게 되면 에러가 발생한다. 

 

중요한 포인트는 rabbit에는  birthDate라는 오브젝트가 있었는데 이것은 Date라는 오브젝트이다. 그래서 getDate와 같은 Date 안에 존재하는 api를 쓸 수가 있다.  하지만 JSON으로 만든 오브젝트의  birthDate를 출력하면 에러가 발생한다. 왜냐면  birthDate는 스트링타입이기 때문이다. JSON으로 만든 Date로 만든 string이 오브젝트로 할당이 된것이다. 그래서 오류가 난 것이다. 

 

stringify와 마찬가지로 조금더 세밀하게 값을 변환하고 싶을 때 콜백 함수를 이용할 수 있다. 

JSON.parse()는 reviver이라는 콜백함수를 전달할 수 있는데 key와 value의 파라미터를 받아서 value대신 key가 birthDate면 새로운 오브젝트를 만들 거고 아니면 원래 그대로 value를 쓰는 함수를 전달해주는 콜백 함수를 key와 value와 함께 전달해주면 위와 같이 getDate가 사용 가능하다. 

 

 

 

 


 

유튜버 드림 코딩 엘리님의 영상을 기반으로 공부한 것을 정리한 내용입니다.