JSON (JavaScript Object Notation)
: 값이나 객체를 나타내주는 범용 포맷으로 RFC 4627 표준에 정의 되어있음
: 본래 자바스크립트에서 사용할 목적으로 만들어진 포맷이지만, 라이브러리를 사용하면
자바스크립트가 아닌 언어에서도 JSON을 충분히 다룰 수 있어 데이터 교환 목적으로 자주 사용
: 특히 클라이언트 측 언어가 자바스크립트일 경우에 많이 사용 (서버 측 언어는 무상관)
JSON 메서드
- JSON.stringify
: 객체를 JSON 형식의 string으로 변환
: 이렇게 변경된 문자열은 JSON으로 인코딩된(JSON-encoded),
직렬화 처리된(serialized), 문자열로 변환된(stringified), 결집된(marshalled) 객체라고 부름
: 객체는 이렇게 문자열로 변환된 후에야 비로소 네트워크를 통해 전송하거나 저장소에 저장할 수 있음
: 객체뿐만 아니라 원시값에도 적용할 수 있음
※ JSON.Stringify를 저장할 수 있는 자료형
: 객체 { ... }
: 배열 [ ... ]
: 원시형 (문자형, 숫자형, 불린형, null)
- JSON.parse
: string으로 된 JSON 형식을 객체로 변환
※ JSON으로 인코딩된 객체가 가지는 일반 객체와 다른 특징
: 문자열은 큰따옴표로 감싸야 함
: JSON에선 작은따옴표나 백틱을 사용할 수 없음
: 객체 프로퍼티 이름은 큰따옴표로 감싸야 함
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.Stringify 호출시 무시되는 프로퍼티
: JSON은 데이터 교환을 목적으로 만들어진 언어에 종속되지 않는 포맷
: 따라서 자바스크립트 특유의 객체인 프로퍼티는 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의 전체 문법
: 순환 참조를 다뤄야 하는 경우같이 전환 프로세스를 정교하게 조정하려면 두 번째 인수를 사용해야 함
: JSON으로 변환하길 원하는 프로퍼티가 담긴 배열을 두 번째 인수로 넘겨주면 이 프로퍼티들만 인코딩할 수 있음
let json = JSON.stringify(value[, replacer, space])
- value
: 인코딩 하려는 값
- replacer
: JSON으로 인코딩 하길 원하는 프로퍼티가 담긴 배열 또는 매핑 함수 function(key, value)
- space
: 서식 변경 목적으로 사용할 공백 문자 수
- 예시
: replacer 함수가 중첩 객체와 배열의 요소까지 포함한 모든 키-값 쌍을 처리
: replacer 함수는 재귀적으로 키-값 쌍을 처리하는데,
함수 내에서 this는 현재 처리하고 있는 프로퍼티가 위치한 객체를 가리킴
: 첫 얼럿창에 예상치 못한 문자열(":[object Object]")이 뜨는걸 볼 수 있는데,
이는 함수가 최초로 호출될 때 {"": meetup} 형태의 "래퍼 객체"가 만들어지기 때문
: replacer함수가 가장 처음으로 처리해야하는 (key, value) 쌍에서 키는 빈 문자열,
값은 변환하고자 하는 객체(meetup) 전체가 되는 것
: 이렇게 replacer 함수를 사용하면 중첩 객체 등을 포함한 객체 전체에서 원하는 프로퍼티만 선택해 직렬화 할 수 있음
let room = {
number: 23
};
let meetup = {
title: "Conference",
participants: [{name: "John"}, {name: "Alice"}],
place: room // meetup은 room을 참조합니다
};
room.occupiedBy = meetup; // room은 meetup을 참조합니다
alert( JSON.stringify(meetup, function replacer(key, value) {
alert(`${key}: ${value}`);
return (key == 'occupiedBy') ? undefined : value;
}));
/* replacer 함수에서 처리하는 키:값 쌍 목록
: [object Object]
title: Conference
participants: [object Object],[object Object]
0: [object Object]
name: John
1: [object Object]
name: Alice
place: [object Object]
number: 23
*/
가독성 높이기
- space
: JSON.stringify(value, replacer, space)의 세 번째 인수 space는 가독성을 높이기 위해
중간에 삽입해 줄 공백 문자 수를 나타냄
: space는 가독성을 높이기 위한 용도로 만들어졌기 때문에 단순 전달 목적이라면 space 없이 직렬화하는 편입니다.
: 아래 예시처럼 space에 2를 넘겨주면 자바스크립트는 중첩 객체를 별도의 줄에 출력해주고
공백 문자 두 개를 써 들여쓰기함
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
}
}
*/
커스텀 toJSON
: toString을 사용해 객체를 문자형으로 변환시키는 것처럼,
객체에 toJSON이라는 메서드가 구현되어 있으면 객체를 JSON으로 바꿀 수 있음
: JSON.stringify는 이런 경우를 감지하고 toJSON을 자동으로 호출
: toJSON은 JSON.stringify()를 직접 호출할 때도 사용할 수 있고, 중첩객체에도 구현하여 사용할 수 있음
let room = {
number: 23,
toJSON() {
return this.number;
}
};
let meetup = {
title: "Conference",
room
};
alert( JSON.stringify(room) ); // 23
alert( JSON.stringify(meetup) );
/*
{
"title":"Conference",
"room": 23
}
*/
JSON.parse()
: JSON.parse를 사용하면 JSON으로 인코딩된 객체를 다시 객체로 디코딩 할 수 있음
- str
: JSON 형식의 문자열
- reviver
: 모든 (key, value) 쌍을 대상으로 호출되는 function(key,value) 형태의 함수로 값을 변경시킬 수 있음
let value = JSON.parse(str, [reviver]);
특정 키를 특정 형식으로 변환하기
- reviver
: JSON.parse()를 할 때 문자열을 Date나 특정 형태의 객체로 만들어야 할 때 사용
- 모든 값은 그대로지만 date만큼은 Date 객체를 반환하는 예
let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';
let meetup = JSON.parse(str, function(key, value) {
if (key == 'date') return new Date(value);
return value;
});
alert( meetup.date.getDate() ); // 이제 제대로 동작하네요!
- 중첩객체에 사용하는 예시
let schedule = `{
"meetups": [
{"title":"Conference","date":"2017-11-30T12:00:00.000Z"},
{"title":"Birthday","date":"2017-04-18T12:00:00.000Z"}
]
}`;
schedule = JSON.parse(schedule, function(key, value) {
if (key == 'date') return new Date(value);
return value;
});
alert( schedule.meetups[1].date.getDate() ); // 잘 동작합니다!
JSON을 사용할 때 흔히 하는 실수들
: JSON은 주석을 지원하지 않음
: 키를 큰따옴표로 감싸지 않아도 되고 주석도 지원해주는 JSON5라는 포맷도 있는데,
이 포맷은 자바스크립트 명세서에서 정의하지 않은 독자적인 라이브러리임
: JSON 포맷이 까다로운 규칙을 가지게 된 이유는 쉽고 빠르며 신뢰할 수 있을 만한 파싱 알고리즘을 구현하기 위함
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] // 이 프로퍼티는 괜찮습니다.
}`;
Refference
'Programming > JavaScript' 카테고리의 다른 글
바닐라 자바스크립트란? (0) | 2022.04.04 |
---|---|
자바스크립트 - 구조 분해 할당 (0) | 2022.04.04 |
모던 자바스크립트 (자료구조와 자료형) 3-8. 위크맵과 위크셋 (0) | 2022.04.03 |
모던 자바스크립트 (자료구조와 자료형) 3-7. 배열 (0) | 2022.04.03 |
모던 자바스크립트 (자료구조와 자료형) 3-6. Date 객체와 날짜 (0) | 2022.04.03 |