320x100
320x100

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

https://ko.javascript.info/json#ref-28

300x250
728x90