글 작성자: 망고좋아
반응형

 

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;

 

 

📌 참고

반응형