본문 바로가기

Language/JavaScript

<자바스크립트> JSON과 메서드

1. JSON

 - 복잡한 객체를 다룰 때, 객체를 보내거나 출력하는 상황에서 객체는 문자열로 전환되어야 한다. 이러한 상황을 유연하게 대처하기위해 JSON이 등장했다.

 

 - JSON(JavaScript Object Notation)은 값이나 객체를 나타내주는 범용 포맷이다.

 

 - 현재에는 라이브러리를 이용하여 다른 언어에서도 사용하게 되어 JSON을 데이터 교환 목적으로 많이 사용한다.

 

 - 대표적인 메서드로 .stringfy(객체를 JSON으로 변경)와 .JSON.parse(JSON을 객체로 변경)이 있다.

 

2. JSON.stringfy

* stringfy

 - stringfy메서드는 말 그대로 객체를 문자열인 JSON으로 변경하는 메서드이다.

 

let student = {
  name: 'Harry',
  age: 22,
  skills: ['html', 'css', 'js']
};

let json = JSON.stringify(student);

console.log(typeof json);
//string

console.log(json);
// {"name":"Harry","age":22,"skills":["html","css","js"]}


 

 - 위와 같이 문자열로 변환된 후 객체는 네트워크를 통해 전송되거나 저장소에 저장될 수 있다.

 

 - JSON으로 인코딩된 객체는 문자열을 큰따옴표로만 감싸야 한다.

 

 - JSON의 프로퍼티 이름도 큰따옴표로 감싸야한다.

 

 - JSON.stringfy는 객체, 배열, 원시형(문자, 숫자, 불린, null)에도 적용할 수 있다.

 

 - 함수 프로퍼티(메서드), 심볼형 프로퍼티, 값이 undefined인 프로퍼티는 호출 시 무시된다.

 

 - JSON.stringfy는 중첩 객체도 문자열로 변환해준다.

 

let school = {
  name: "JS",
  room: {
    number: 1,
    students: ["Harry", "IU"]
  },
  location: 'KOREA'
};
console.log(JSON.stringify(school));
// {"name":"JS","room":{"number":1,"students":["Harry","IU"]},"location":"KOREA"}

 

 - 참고로 순환참조가 있을 경우 에러가 나므로 주의하자.

 

* replacer

 - JSON.stringfy의 전체문법은 아래와 같다.

 

let json = JSON.stringfy(value[, replacer, space])

 

 - value : 위에서 봐왔던 인코딩 하려는 값이다.

 - replacer : 인코딩 하길 원하는 프로퍼티가 담긴 배열 또는 매핑 함수이다.

 - space : 서식 변경 목적으로 사용할 공백 문자 수이다.

 

 - 보통은 value인수 하나만 넘겨서 사용하지만 순환참조와 같이 정교한 조정이 필요한 경우 두 번째 인수를 사용한다.

 

let room = {
  number: 23
};

let school = {
  school: "JS",
  students: [{name: "Harry"}, {name: "IU"}],
  place: room 
};

room.occupiedBy = school;

console.log( JSON.stringify(school, ['school', 'students', 'place', 'name', 'number']) );

// {
//   "school":"JS",
//   "students":[{"name":"Harry"},{"name":"IU"}],
//   "place":{
//     "number":23
//   }
// }

 

 - 위와 같이 배열에 프로퍼티를 명시하면 occupiedBy를 제외하고 프로퍼티들을 직렬화시킬 수 있다.

 

 - 하지만 배열이 점점 길어지면 가독성이 떨어질 뿐아니라 수정하기도 힘들 수 있다.

 

 - 이번에는 replacer함수를 사용해보자.

 

let room = {
  number: 23
};

let school = {
  school: "JS",
  students: [{name: "Harry"}, {name: "IU"}],
  place: room 
};

room.occupiedBy = school;

console.log( JSON.stringify(school, function replacer(key, value) {
  return (key == 'occupiedBy') ? undefined : value;
}));

// {
//   "school":"JS",
//   "students":[{"name":"Harry"},{"name":"IU"}],
//   "place":{
//     "number":23
//   }
// }

 

 - 키가 occupiedBy일 경우 undefined로 값을 주어 JSON에서 제외되도록하였다.

 

3. toJSON

* toJSON

 - 객체에 toJSON이라는 메서드가 구현되어 있으면 객체를 JSON으로 바꿀 수 있다. 이 때 JSON.stringfy는 이런 경우를 감지하여 toJSON을 자동으로 호출한다.

 

 - 예를 들어 Date는 내장메서드 toJSON을 갖고 있으므로 자동으로 date값이 문자열로 변환된다.

 

let test = {
  name: "test",
  date: new Date()
}

console.log(JSON.stringify(test))
//{"name":"test","date":"2021-04-06T01:20:39.254Z"}

 

* 커스텀 toJSON

 - 직접 커스텀 메서드를 추가할 수도 있다.

 

let room = {
  number: 15,
  toJSON() {
    return this.number;
  }
};

let school = {
  name: "JS",
  room
};

console.log( JSON.stringify(room) ); 
// 15

console.log( JSON.stringify(school) );
// {"name":"JS","room":15}

 

 - room에 toJSON메서드가 존재하여 JSON.stringfy호출 시 room은 number의 값만을 가지는 것을 알 수 있다.

 

4. JSON.parse

* JSON.parse

 - JSON.parse메서드를 이용해 JSON으로 인코딩된 객체를 다시 객체로 디코딩 할 수 있다.

 

let value = JSON.parse(str, [reviver]);

 

 - 문법은 위와 같으며 str을 JSON형식의 문자열을 의미한다.

 

 - reviver은 모든 키 값 쌍을 대상으로 호출되는 function(key, value) 형태의 함수로 값을 변경시킨다.

 

let userData = '{ "name": "Harry", "age": 22, "items": [0,1,2,3] }';

let user = JSON.parse(userData);

console.log( user.items[1] ); 
// 1

 

 - parse는 JSON형식의 문자열에는 모두 사용가능하므로 배열문자열에도 사용가능하다. 물론 위와 같이 중첩 객체에도 사용 가능하다.

 

* reviver

 - 단순히 parse를 사용할 경우 종종 에러를 마주할 수 있다.

 

let test = '{"name":"test","date":"2021-04-06T01:20:39.254Z"}';

let result = JSON.parse(test);

console.log( result.date.getDate() );
// 에러

 

 - 위의 경우 result.date의 값은 Date객체가 아닌 문자열이므로 getDate메서드를 호출하지 못하고 에러가 난다. 

 

 - 이 경우 문자열을 Date로 전환해보자.

 

let test = '{"name":"test","date":"2021-04-06T01:20:39.254Z"}';

let result = JSON.parse(test, function(key, value) {
  if (key == 'date') return new Date(value);
  return value;
});

console.log( result.date.getDate() );
// 6

 

 - reviver을 사용하여 date 키를 가진 값은 Date객체를 반환하도록 구현하였다.

 

 


 

 

참고

 

 

모던 자바스크립트 튜토리얼

 

모던 JavaScript 튜토리얼

 

ko.javascript.info