[자바스크립트] JSON.stringify(value), JSON.parse()
글 작성자: 망고좋아
반응형
JSON과 메서드
- Client와 Server와 통신하기 위해서는 XMLHttpRequest, fetch() API를 사용해서 통신할 수 있다.
- XML 많이 사용되지 않고 JSON을 많이 사용한다.
- JavaScript Object Notation (JSON)은 Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷이다.
- 웹 애플리케이션에서 데이터를 전송할 때 일반적으로 사용한다.
- JSON은 문자열 형태로 존재한다.
- 데이터를 주고받을 때 쓸 수 있는 가장 간단한 파일 포맷이다.
- 텍스트를 기반으로한 가볍고 가독성이 좋다.
- key와 value로 이루어져 있다.
- 데이터를 서버와 주고받을 때 직렬화를 위해서 사용한다.
- 프로그래밍 언어나 플랫폼에 상관없이 사용할 수 있다.
JSON
- 토끼 객체를 서버로 전송할 때는 {key: value} String 타입으로 전송한다.
- 반대로 서버에서 데이터를 받아올 때도 string 타입으로 받아와서 토끼라는 객체로 변환해서 브라우저에 표기하게 되는 것이다.
JSON 공부 포인트
- 객체를 어떻게 serialize (직렬화) 해서 json으로 변환할 건지?
- 직렬화된 json을 어떻게 deserialize(역직렬화)해서 객체로 변환할 건지?
JSON.stringify(value)
- JSON.stringify() 메소드는 인수로 전달받은 자바스크립트 객체를 문자열로 변환하여 반환한다.
// JSON.stringify(student)를 호출하자 student가 문자열로 바뀐다.
let student = {
name: 'John',
age: 30,
isAdmin: false,
courses: ['html', 'css', 'js'],
wife: null
};
let json = JSON.stringify(student);
alert(typeof json); // 문자열이다.
alert(json);
/* JSON으로 인코딩된 객체:
{
"name": "John",
"age": 30,
"isAdmin": false,
"courses": ["html", "css", "js"],
"wife": null
}
*/
- 이렇게 변경된 문자열은 JSON으로 인코딩 된(JSON-encoded), 직렬화 처리된(serialized), 문자열로 변환된(stringified), 결집된(marshalled) 객체라고 부른다.
- 객체는 이렇게 문자열로 변환된 후에야 비로소 네트워크를 통해 전송하거나 저장소에 저장할 수 있다.
const rabbit = {
name: 'tori',
color: 'white',
size: null,
birthDate: new Date(),
jum: () => { // 함수는 제외된다, 심볼도 제외
console.log(`${name} cna jump!`);
},
};
let json = JSON.stringify(rabbit);
console.log(json)
// {"name":"tori","color":"white","size":null,"birthDate":"2021-07-13T04:06:30.441Z"}
// 세밀하게 통제
const rabbit = {
name: 'tori',
color: 'white',
size: null,
birthDate: new Date(),
jum: () => {
console.log(`${name} cna jump!`);
},
};
let json = JSON.stringify(rabbit, ["name"]); // 이름만 가져오기
console.log(json) //{"name":"tori"}
//replacer 사용
const rabbit = {
name: 'tori',
color: 'white',
size: null,
birthDate: new Date(),
jum: () => {
console.log(`${name} cna jump!`);
},
};
let json = JSON.stringify(rabbit, (key, value) => {
console.log(`key: ${key}, value: ${value}`);
return key === 'name' ? 'ellie' : value;
});
console.log(json)
/*
key: , value: [object Object] // 토끼 객체를 감싸고 있는 최상위 것을 가져온다.
json.js:12 key: name, value: tori
json.js:12 key: color, value: white
json.js:12 key: size, value: null
json.js:12 key: birthDate, value: 2021-07-13T04:11:51.183Z
json.js:12 key: jum, value: () => {
console.log(`${name} cna jump!`);
}
json.js:16 {"name":"ellie","color":"white","size":null,"birthDate":"2021-07-13T04:11:51.183Z"}
*/
일반 객체와 JSON으로 인코딩 된 객체의 차이점
- 문자열은 큰따옴표로 감싸야한다. JSON에선 작은따옴표나 백틱을 사용할 수 없다.(
'John'
이"John"
으로 변경된 것을 보고 확인 가능!) - 객체 프로퍼티 이름은 큰따옴표로 감싸야한다.(age:30이
"age":30
으로 변한 것으로 확인)
JSON.stringify는 객체뿐만 아니라 원시 값에도 적용할 수 있다.
- 객체 { ... }
- 배열 [ ... ]
- 원시형
- 문자형
- 숫자형
- 불린형 값 true와 false
- null
// 숫자를 JSON으로 인코딩하면 숫자다.
alert( JSON.stringify(1) ) // 1
// 문자열을 JSON으로 인코딩하면 문자열이 된다(다만, 큰따옴표가 추가됩니다).
alert( JSON.stringify('test') ) // "test"
alert( JSON.stringify(true) ); // true
alert( JSON.stringify([1, 2, 3]) ); // [1,2,3]
- JSON은 데이터 교환을 목적으로 만들어진 언어에 종속되지 않는 포맷이다.
- 따라서 자바스크립트 특유의 객체 프로퍼티는
JSON.stringify
가 처리할 수 없다.
JSON.stringify 호출 시 무시되는 프로퍼티
- 함수 프로퍼티 (메서드)
- 심볼형 프로퍼티 (키가 심볼인 프로퍼티)
- 값이
undefined
인 프로퍼티
let user = {
sayHi() { // 무시
alert("Hello");
},
[Symbol("id")]: 123, // 무시
something: undefined // 무시
};
alert( JSON.stringify(user) ); // {} (빈 객체가 출력됨)
JSON.stringify의 장점 중 하나는 중첩 객체도 알아서 문자열로 바꿔준다.
let meetup = {
title: "Conference",
room: {
number: 23,
participants: ["john", "ann"]
}
};
alert( JSON.stringify(meetup) );
/* 객체 전체가 문자열로 변환되었다.
{
"title":"Conference",
"room":{"number":23,"participants":["john","ann"]},
}
*/
⚠️ JSON.stringify를 사용할 때 순환 참조가 있으면 원하는 대로 객체를 문자열로 바꾸는 게 불가능하다.
let room = {
number: 23
};
let meetup = {
title: "Conference",
participants: ["john", "ann"]
};
meetup.place = room; // meetup은 room을 참조합니다.
room.occupiedBy = meetup; // room은 meetup을 참조합니다.
JSON.stringify(meetup); // Error: Converting circular structure to JSON
replacer로 원하는 프로퍼티만 직렬화 하기
JSON.stringify 의 전체 문법
let json = JSON.stringify(value[, replacer, space])
value : 인코딩하려는 값
replacer : JSON으로 인코딩하길 원하는 프로퍼티가 담긴 배열. 또는 매핑 함수 function(key, value)
space : 서식 변경 목적으로 사용할 공백 문자 수
- 대다수의 경우
JSON.stringify
엔 인수를 하나만 넘겨서 사용한다. - 그러나 순환 참조를 다뤄야 하는 경우같이 전환 프로세스를 정교하게 조정하려면 두 번째 인수를 사용해야 한다.
let room = {
number: 23
};
let meetup = {
title: "Conference",
participants: [{name: "John"}, {name: "Alice"}],
place: room // meetup은 room을 참조합니다.
};
room.occupiedBy = meetup; // room references meetup
alert( JSON.stringify(meetup, ['title', 'participants']) );
// {"title":"Conference","participants":[{},{}]}
- 배열에
name
을 넣지 않아서 출력된 문자열의participants
가 텅 비어버렸다. -> 규칙이 까다로워서 발생한 문제
순환 참조를 발생시키는 프로퍼티 room.occupiedBy만 제외하고 모든 프로퍼티를 배열에 넣기
let room = {
number: 23
};
let meetup = {
title: "Conference",
participants: [{name: "John"}, {name: "Alice"}],
place: room // meetup references room
};
room.occupiedBy = meetup; // room references meetup
alert( JSON.stringify(meetup, ['title', 'participants', 'place', 'name', 'number']) );
/*
{
"title":"Conference",
"participants":[{"name":"John"},{"name":"Alice"}],
"place":{"number":23}
}
*/
space로 가독성 높이기
JSON.stringify(value, replacer, space)
의 세 번째 인수space
는 가독성을 높이기 위해 중간에 삽입해 줄 공백 문자 수를 나타낸다.
let user = {
name: "John",
age: 25,
roles: {
isAdmin: false,
isEditor: true
}
};
alert(JSON.stringify(user, null, 2));
/* 공백 문자 두 개를 사용하여 들여쓰기함:
{
"name": "John",
"age": 25,
"roles": {
"isAdmin": false,
"isEditor": true
}
}
*/
/* JSON.stringify(user, null, 4)라면 아래와 같이 좀 더 들여써진다.
{
"name": "John",
"age": 25,
"roles": {
"isAdmin": false,
"isEditor": true
}
}
*/
JSON.parse()
- JSON.parse() 메소드는 JSON.stringify() 메소드와는 반대로 인수로 전달받은 문자열을 자바스크립트 객체로 변환하여 반환한다.
- 즉, JSON으로 인코딩 된 객체를 다시 객체로 디코딩.
기본 문법
let value = JSON.parse(str, [reviver]);
- str : JSON 형식의 문자열
- reviver : 모든
(key, value)
쌍을 대상으로 호출되는 function(key,value) 형태의 함수로 값을 변경시킬 수 있다.
- text에는 변환할 문자열을 전달한다.
- 해당 문자열은 반드시 유효한 JSON 형식의 문자열이어야 한다.
- 만약 JSON 형식에 맞지 않는 문자열을 전달하면, 자바스크립트는 오류를 발생시킨다.
// 문자열로 변환된 배열
let numbers = "[0, 1, 2, 3]";
numbers = JSON.parse(numbers);
alert( numbers[1] ); // 1
// 중첩 객체에도 사용할 수 있다.
let userData = '{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }';
let user = JSON.parse(userData);
alert( user.friends[1] ); // 1
// reviver사용해서 문자열로 만들어진 date를 다시 객체로 바꾸기
const rabbit = {
name: 'tori',
color: 'white',
size: null,
birthDate: new Date(),
jum: () => {
console.log(`${name} cna jump!`);
},
};
json = JSON.stringify(rabbit);
const obj = JSON.parse(json, (key, value) => {
console.log(`key: ${key}, value: ${value}`);
return key === 'birthDate' ? new Date(value) : value;
});
console.log(obj.birthDate.getDate()) // 13. reviver 사용해서 다시 new Date()로 바꿔줘서 원하는 값을 가져올 수 있다.
/*
key: name, value: tori
json.js:26 key: color, value: white
json.js:26 key: size, value: null
json.js:26 key: birthDate, value: 2021-07-13T04:21:43.792Z
json.js:26 key: , value: [object Object]
json.js:30 13
*/
실수하지 말 것!
let json = `{
name: "John", // 실수 1: 프로퍼티 이름을 큰따옴표로 감싸지 않았습니다.
"surname": 'Smith', // 실수 2: 프로퍼티 값은 큰따옴표로 감싸야 하는데, 작은따옴표로 감쌌습니다.
'isAdmin': false // 실수 3: 프로퍼티 키는 큰따옴표로 감싸야 하는데, 작은따옴표로 감쌌습니다.
"birthday": new Date(2000, 2, 3), // 실수 4: "new"를 사용할 수 없습니다. 순수한 값(bare value)만 사용할 수 있습니다.
"friends": [0,1,2,3] // 이 프로퍼티는 괜찮습니다.
}`;
- JSON은 주석을 지원하지 않는다
toJSON()
- 자바스크립트의 toJSON() 메소드는 자바스크립트의 Date 객체의 데이터를 JSON 형식의 문자열로 변환하여 반환한다.
- 따라서 이 메소드는 Date.prototype 객체에서만 사용할 수 있다.
var date = new Date(); // 자바스크립트 Date 객체
var str = date.toJSON(); // Date 객체를 JSON 형식의 문자열로 변환함.
document.getElementById("json").innerHTML = date + "<br>";
document.getElementById("json").innerHTML += str;
📌 참고
반응형
'프로그래밍 > JavaScript' 카테고리의 다른 글
[자바스크립트] getter와 setter (0) | 2021.07.15 |
---|---|
[자바스크립트] 다시 보는 화살표 함수 (0) | 2021.07.15 |
[자바스크립트] 타이머 관련 메소드(setTimeout, clearTimeout, setInterval), 중첩 setTimeout (0) | 2021.07.12 |
[자바스크립트] 변수의 유효범위와 클로저 (0) | 2021.07.10 |
[자바스크립트] Array.from(), 배열로 만들어주기 (0) | 2021.07.10 |
댓글
이 글 공유하기
다른 글
-
[자바스크립트] getter와 setter
[자바스크립트] getter와 setter
2021.07.15 -
[자바스크립트] 다시 보는 화살표 함수
[자바스크립트] 다시 보는 화살표 함수
2021.07.15 -
[자바스크립트] 타이머 관련 메소드(setTimeout, clearTimeout, setInterval), 중첩 setTimeout
[자바스크립트] 타이머 관련 메소드(setTimeout, clearTimeout, setInterval), 중첩 setTimeout
2021.07.12 -
[자바스크립트] 변수의 유효범위와 클로저
[자바스크립트] 변수의 유효범위와 클로저
2021.07.10