// Browser 에서 동작하고 있는 website 같은 client 들이 어떻게 server 와 통신할수 있는지 정의 -> http
// hypertext transfer protocal
// 어떻게 hypertext 를 서로주고받을 것인지 규약한 protocol의 하나
// client 가 server에게 request, server는 response 해준다.
// hypertext 는 hyperlink 뿐만 아니라 문서, 이미지도 포함이다.
// 이렇게 데이터를 받아올 수 있는 방법으로는 ajax (asynchronous javascript and xml) 이 있다.
// 동적으로 서버에게 데이터를 주고받을 수 있는 기술  XMLHttpRequest 
// 또는 최신으로 fetch() API 도 있다.
// xml 은 불필요한 태그도 많이 들어가고 파일의 크기도 커지면서 가독성도 좋지 않아서 추세에 밀리고 있다.
// 요즘은 JSON 을 많이 쓰고 있다. javaScript Object Notation
// Object { key: value } 
// 서버와 데이터를 주고받을 때 또는 서버와 통신하지 않아도 object를 file system에 저장할 때도 JSON 타입을 이용한다.

// JSON 특징
// 데이터를 주고받을 때 쓸 수 있는 간단한 기술
// 텍스트를 기반으로 한 가벼운 구조를 가지고 있다.
// 읽기 쉽다.
// KEY와 VALUE 로 이루어져 있다.
// 데이터를 서버와 주고 받을 때 serialization (직렬화) 하기 위해서 사용한다.
// 프로그래밍 언어와 플랫폼에 상관없이 사용가능하다.

// 어떠한 object 를 서버에 전송할 때는 {key: value} 의 string 타입으로 서버에 전송하게 된다.
// 서버에서 다시 받아올 때도 {key: value} 의 string 타입으로 받아와서 다시 Object로 변환해서 브라우저에 표기한다.

// 어떻게 serialize 할 것인지, 반대로 또 어떻게 deserialize 할 것인지?

// JSON
// Javascript Object Notation

// 1. Object to JSON
// stringfy(obj)
let json = JSON.stringify(true);
console.log(json);

json = JSON.stringify(['apple', 'banana']);
console.log(json); // ["apple","banana"]

const rabbit = {
    name: 'tori',
    color: 'white',
    size: null,
    birthDate: new Date(),
    //symbol: Symbol('id'),
    jump: () => {
        console.log(`${this.name} can jump!`);
    },
};

json = JSON.stringify(rabbit);
console.log(json); //{"name":"tori","color":"white","size":null,"birthDate":"2021-03-13T05:57:25.745Z"}
// jump 라는 함수는 json 에 포함되어있지 않다. 왜???
// 함수는 object에 있는 data가 아니기 때문!!
// symbol 도 포함되지 않는다. js에만 있는 특별한 것 이기 때문!!

json = JSON.stringify(rabbit, ['name', 'color']); // 원하는 property 만 정해서 넘겨주면 해당 key만 넘어간다.
console.log(json); // {"name":"tori","color":"white"}

console.clear();

// 좀 더 세밀하게 통제하고 싶을 때 callback func 사용
json = JSON.stringify(rabbit, (key, value) =>{
    console.log(`key: ${key}, value: ${value}`);
    return key === 'name' ? 'malza' : value;    
		//return value;
});
//key: , value: [object Object] // 제일 최상위가 먼저 전달된다.
//key: name, value: tori
//key: color, value: white
//key: size, value: null
//key: birthDate, value: 2021-03-20T08:45:50.686Z
//key: jump, value: () => {
//        console.log(`${this.name} can jump!`);
//   }

console.log(json); // {"name":"malza","color":"white","size":null,"birthDate":"2021-03-13T06:07:16.250Z"}
// malza 로 바뀐것 확인 가능하다.

// overloading 
// 함수의 이름은 동일하지만 어떤 param을 전달하냐, 몇개를 전달하냐에 따라 다른 함수를 호출 할 수 있는 기술

// 2. JSON to Object
// parse(json)

console.clear();
json = JSON.stringify(rabbit);
const obj = JSON.parse(json, (key, value) => { // json 으로 넘기고 받아올 때 date를 object로 받고 싶다면 revive callback
    console.log(`key: ${key}, value: ${value}`);
    return key === 'birthDate' ? new Date(value) : value;
});
console.log(obj);
//rabbit.jump();
//obj.jump();  //  json 으로부터 만들어진 obj 에는 함수 jump가 없다.

//console.log(rabbit.birthDate.getDate());
// birthDate 를 new 를 통해 생성해 주지 않으면 error가 난다.
// json 으로부터 다시 만들어질 때 string으로 변환되었기 때문이다.
console.log(obj.birthDate.getDate()); // 2021-03-13T10:26:20.147Z

https://ko.javascript.info/json

callback