본문 바로가기
공부일지/Javascript

JavaScript 문법. JSON (stringify, parse)

by 곰인간 2023. 2. 15.

엉뚱한 짓을 하고 다닐 때 봤던 JSON

말로만 들어보고 그냥 눈으로만 봤지 어떻게 동작하고 어떤 기능이 있는지 잘 몰랐다.


일단, 오늘 도움을 주신우리의 지식을 풍족하게 해주실 MDN Web Docs 선생님과

유튜브 드림코딩 엘리 님의  영상을 보고 작성함을 알려드립니다.

아니, 대체 JSON이 뭐죠?

* 참고 자료 : MDN Web Docs - JSON으로 작업하기

JavaScript Object Notation (JSON)은
Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷입니다. 웹 어플리케이션에서 데이터를 전송할 때 일반적으로 사용합니다.


(서버에서 클라이언트로 데이터를 전송하여 표현하려거나 반대의 경우)

JSON  Douglas Crockford가 널리 퍼뜨린 Javascript 객체 문법을 따르는 문자 기반의 데이터 포맷입니다.
JSON이 Javascript 객체 문법과 매우 유사하지만
딱히 Javascript가 아니더라도 JSON을 읽고 쓸 수 있는 기능이
다수의 프로그래밍 환경에서 제공됩니다.

JSON은 문자열 형태로 존재합니다 — 네트워크를 통해 전송할 때 아주 유용하죠.
데이터에 억세스하기 위해서는 네이티브 JSON 객체로 변환될 필요가 있습니다.
별로 큰 문제는 아닌 것이
Javascript는 JSON 전역 객체를 통해 문자열과 JSON 객체의 상호변환을 지원합니다.

라고 MDN Web Docs 선생님께서 말씀을 하시네요.

말로만 들어서는 그냥 어렵습니다.


JSON은 쉽게 말해 object를 JSON으로 변환하는 api인 stringify()와

JSON을 다시 object로 변환하는 api인 parse가 있습니다.

1. JSON.stringify();

let json = JSON.stringify(true); // boolean type도 json으로 변환 가능
console.log(json); // true

json = JSON.stringify(['곰', '인간']); // 배열을 json으로 변환
console.log(json); // ["곰","인간"] 
// 기존 배열은 싱글쿼터로 ['곰', '인간']으로 표시 했지만 
//json으로 변환하면 더블쿼터 ["곰","인간"]로 표시 (json의 규격사항)

 

위에서 설명했듯이 JSON은 Javascript 객체 리터럴 문법을 따르는 문자열입니다. JSON 안에는 마찬가지로 Javascript의 기본 데이터 타입인 문자열, 숫자, 배열, 불리언 그리고 다른 객체를 포함할 수 있습니다.

 

const 인간 = {
    이름: "곰인간",
    나이: "3X",
    몸무게: null,
    키: "178",
    생일: new Date(),
    울음소리: () => {
        console.log(`${인간.이름}이 울부 짖었다. 쿠오오`)
    },
};

json = JSON.stringify(인간);
console.log(json); 
// {"이름":"곰인간","나이":"3X","몸무게":null,"키":"178","생일":"2023-02-15T05:21:58.894Z"}
// 울음소리 함수는 json에 포함되지 않는다. 함수는 object의 데이터가 아님

하지만, 위에 코드처럼 함수로 표시된 부분은 JSON에 포함되지 않습니다. 

왜냐하면 함수는 object의 데이터가 아니기 때문입니다.

또한, 자바스크립트 자체의 symbol 같은 데이터도 포함되지 않습니다.

const 인간 = {
    이름: "곰인간",
    나이: "3X",
    몸무게: null,
    키: "178",
    생일: new Date(),
    symbol: Symbol("id"), // console.log를 찍어보면 symbol은 표기가 안됨.
    울음소리: () => {
        console.log(`${인간.이름}이 울부 짖었다. 쿠오오`)
    },
};

json = JSON.stringify(인간);
console.log(json); 
// {"이름":"곰인간","나이":"3X","몸무게":null,"키":"178","생일":"2023-02-15T05:21:58.894Z"}

null값은 더블쿼터로 표시되지않네요.

json = JSON.stringify(인간, ['이름']); 
//이름만 json으로 하고 싶으면 배열에 프로퍼티 이름만 전달하면 이름만 포함되어 나옴. 

console.log(json); 
// {"이름":"곰인간"} 

json = JSON.stringify(인간, ['이름', '나이']);
console.log(json); 
// {"이름":"곰인간","나이":"3X"}

위 코드처럼 배열에 프로퍼티를 전달하면 해당 프로퍼티 값만 나옵니다.

json = JSON.stringify(인간, (key, value) => {
    console.log(`key: ${key}, value: ${value}`);
    return value;
}); // json변환되는것을 통제하고 싶으면 callback함수를 이용
//모든 key와 value가 callback함수에 전달

key: , value: [object Object] // 인간의 object를 싸고있는 제일 최상의 것이 먼저 전달
key: 이름, value: 곰인간
key: 나이, value: 3X
key: 몸무게, value: null
key: 키, value: 178
key: 생일, value: 2023-02-15T05:28:16.421Z
key: 울음소리, value: () => {
        console.log(`${인간.이름}이 울부 짖었다. 쿠오오`)
    } 
console.log(json); 
// {"이름":"곰인간","나이":"3X","몸무게":null,"키":"178","생일":"2023-02-15T05:28:16.421Z"}

 

 

callback함수를 전달하게 되면 key와 value에 따라서 모든 key와 value가 전달된다.

json = JSON.stringify(인간, (key, value) => {
    console.log(`key: ${key}, value: ${value}`);
    return key === '이름' ? '보통인간' : value;
    // 만약, key가 '이름'이라는 것이 들어오면 '보통인간'이라는 value로 설정하고,
	//key가 '이름'이 아니면 기존 value값으로 설정한다.
});
console.log(json);
// {"이름":"보통인간","나이":"3X","몸무게":null,"키":"178","생일":"2023-02-15T05:36:28.617Z"}

 

이름의 value값이 곰인간에서 보통인간으로 변경


2. JSON.parse();

json = JSON.stringify(인간);
const obj = JSON.parse(json);
console.log(obj); // {이름: '곰인간', 나이: '3X', 몸무게: null, 키: '178', 생일: '2023-02-15T05:37:54.158Z'}
인간.울음소리(); // 곰인간이 울부 짖었다. 쿠오오
obj.울음소리(); // Uncaught TypeError: obj.울음소리 is not a function
// 변환한 obj에 함수(울음소리)는 json으로 변경될 때 포함되어 있지않아서 오류가 발생

위에서 설명했듯이 함수는 JSON으로 변환하지 않는다.

고로, JSON으로 변환한 obj에는 울음소리 라는 함수가 포함되지 않는다.

console.log(인간.생일.getDate()); // 15
console.log(obj.생일.getDate()); 
// Uncaught TypeError: obj.생일.getDate is not a function
// 에러가 발생! 생일은 string이기 때문에
console.log(json); 
// {"이름":"곰인간","나이":"3X","몸무게":null,"키":"178","생일":"2023-02-15T05:51:33.106Z"}

JSON으로 만든 데이터 자체에 있는 string이 obj에 할당이 된 것.


(생일: new Date()) => ("생일":"2023-02-15T05:51:33.106Z")
object에서 JSON으로 변환한 '생일'이 string형태로 만들어짐.
("생일":"2023-02-15T05:51:33.106Z")
반대로, JSON에서 object로 변환해도 string형태로 가져온다.

 

const obj = JSON.parse(json, (key, value) => {
    console.log(`key: ${key}, value: ${value}`);
    return value;
})

key: 이름, value: 곰인간
key: 나이, value: 3X
key: 몸무게, value: null
key: 키, value: 178
key: 생일, value: 2023-02-15T05:53:41.254Z
key: , value: [object Object]

 

const obj = JSON.parse(json, (key, value) => {
    console.log(`key: ${key}, value: ${value}`);
    return key === '생일' ? new Date(value) : value;
    //key가 '생일'이면, new Date()라는 object를 새로 만들거고, 아니면 기존 value를 그대로 쓰겠어
})
console.log(obj); 
// {이름: '곰인간', 나이: '3X', 몸무게: null, 키: '178', 생일: Wed Feb 15 2023 14:57:49 GMT+0900 (한국 표준시)}
console.log(인간.생일.getDate()); // 15
console.log(obj.생일.getDate()); // 15
//console.log(obj.생일.getDate());가 아까전과 다르게 15라고 출력되었다.
//기존에 '생일'의 new Date()라는 value는2023-02-15T05:51:33.106의 string이었는데
// callback 함수로 받아온 new Date() Wed Feb 15 2023 14:57:49 GMT+0900 (한국 표준시)이렇게 표시된다.
//기존에 new Date()는 JSON으로 변환되면서 string이 되었고,
//callback 함수로 받아온 new Date();는 typeof를 찍어보면 object라는 것을 알 수 있다.

 


써놓고도 잘 모르겠으니 열번은 더 봐야겠다.

중구난방으로 써져있지만 어쩌겠는가 모르겠으면 알때까지 보면 되는것을..

댓글