네트워크를 통해 객체를 어딘가에 보낼 때 객체를 출력해야 한다면 객체를 문자열로 전환해야 합니다.
이때 전환된 문자열에는 원하는 정보가 있는 객체 프로퍼티 모두가 포함되어야 합니다.
개발 과정에서 프로퍼티가 추가되거나 삭제, 수정 된다고 계속해서 toString을 통해 내용을 추가(삭제, 수정)을 할 수 없습니다.
JSON(JavaScript Object Notation)은 값이나 객체를 나타내주는 범용 포맷입니다. JSON을 데이터 교환 목적으로 사용하는 경우가 많습니다. 특히 클라이언트측 언어가 자바스크립트일 때 많이 사용됩니다. 서버 측 언어는 아무거나 상관없습니다.
ex) JSON.stringify
let student = {
name: "John",
age: 31,
isAdmin: false,
courses: ['html', 'css', 'js'],
wife: null
};
let json = JSON.stringify(student);
console.log(json);
/*
{
"name": "John",
"age": 31,
"isAdmin": false,
"courses": ["html", "css", "js"],
"wife": null
}
*/
JSON.stringify(student)를 호출하면 student는 문자열로 바뀝니다.
이렇게 변경된 문자열은 JSON으로 인코딩 된 직렬화 처리된(serialized), 문자열로 변환된(stringified), 결집된(marshalled)객체라고 부릅니다. 객체는 이렇게 문자열로 변환된 후에야 비로소 네트워크를 통해 전송하거나 저장소에 저장할 수 있습니다.
JSON으로 인코딩 된 객체는 일반 객체와 다릅니다.
JSON.stringify는 객체 뿐 아니라 원시값에도 적용할 수 있습니다.
ex) JSON.stringify 원시형
console.log(JSON.stringify(1)); // 1 출력
console.log(JSON.stringify('test'); "test" 출력
// 문자열을 JSON으로 인코딩하면 큰 따옴표가 추가됩니다.
console.log(JSON.stringify(true)); // true 출력
console.log(JSON.stringify([1,2,3]); // [1,2,3] 출력
let hotel = {
name: "Royal",
room: {
number: 20,
member: ["KJ", "SJ"]
}
};
console.log(JSON.stringify(hotel);
/*
{
"name": "Royal",
"room": {"number": 20, "member": ["KJ", "SJ"]}, 출력
*/
순환 참조가 있을 경우 에러가 발생합니다.
ex)
let room = {
number: 20
};
let hotel = {
name: "Royal",
member: ["KJ", "SJ"]
};
hotel.place = room;
console.log(JSON.stringify(hotel));
// 상단의 hotel.place 에서 room을 참조해서 에러가 발생합니다.
ex) 기본 문법
let json = JSON.stringify(value, [, replacer, space])
일반적으로 replacer를 사용하지 않습니다. (순환 참조를 다뤄야 하는 경우 사용됩니다.)
ex) replace 예시
let room = {
number: 20
};
let hotel = {
name: "Royal",
member: [{name: "KJ"}, {name: "SJ"}],
place: room // hotel은 room을 참조합니다.
}; // replacer를 통한 순환 참조 에러 해결
room.occupiedBy = hotel;
console.log(JSON.stringify(hotel, ['name', 'member']));
// {"name":"Royal", "member":[{},{}]} 출력
에러 없이 잘 출력됩니다. 하지만 원래 KJ, SJ까지 출력 될 것으로 기대했지만 배열에 name을 넣지 않아 출력된 문자열의 member가 비어버렸습니다.
(추가적으로 공부가 더 필요합니다.)
JSON.stringify(value, replacer, space)의 세 번 째 인수 space를 사용하면 가독성을 높일 수 있습니다.
space는 단순히 가독성을 높이기 위해 만들어졌습니다. 일반적으로는 space없이 직렬화하는 편이기 때문에 자주 사용되는 문법은 아닙니다.
let user = {
name: "KJ",
age: 31,
roles: {
isAdmin: false,
isEditor: true
}
};
console.log(JSON.stringify(user, null, 4));
/*
{
"name": "KJ",
"age": 31,
"roles": {
"isAdmin": false,
"isEditor": true
} // isAdmin, isEditor가 4만큼 들여쓰기 됩니다.
}
*/
JSON으로 인코딩 된 객체를 다시 객체로 디코딩 할 수 있습니다.
ex) JSON.parse 기본문법
let value = JSON.parse(str, [reviver]);
ex) JSON.parse
let userData = {
"name": "KJ",
"age": 31,
"isAdmin": false,
"friends": [0,1,2,3]
}
let user = JSON.parse(userData);
console.log(user.friends[1]); // 1 출력
## JSON 주의 사항
큰 따옴표, 그리고 주석을 지원하지 않습니다.
주석을 추가할 경우 유효하지 않은 형식으로 에러가 발생합니다.
JSON 포맷은 까다로운 규칙을 가지고 있는 만큼 모두의 약속이기 때문에 쉽고 빠르며 신뢰할 수 있는 알고리즘 구현이 가능해집니다.