ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Javascript] JSON, stringfy, parse, toJSON, 깊은복사,structuredClone
    웹/JavaScript 2023. 1. 13. 09:31

    I. JSON JavaScript Object Notation

    • 복잡한 구조를 가질 수 있는 데이터를 한 줄의 문자열로 표현
    • 서버와 클라이언트 등 데이터들을 주고받는 주체들 사이에 널리 사용

     


     

    II. JSON 객체의 정적 메서드

    1. stringify - 객체를 문자열로 직렬화 serialize

    const person = {
    name: '김달순',
    age: 23,
    languages: ['Korean', 'English', 'French'],
    education: {
    school: '한국대',
    major: ['컴퓨터공학', '전자공학'],
    graduated: true,
    }
    };
    const personStr = JSON.stringify(person);
    console.log(typeof personStr);
    console.log(personStr);

    데이터 형태별 직렬화 결과

    [
    JSON.stringify(1),
    JSON.stringify(Infinity), // ⚠️
    JSON.stringify(NaN), // ⚠️
    JSON.stringify('가나다'),
    JSON.stringify(true),
    JSON.stringify(null),
    JSON.stringify(undefined),
    JSON.stringify([1, 2, 3]),
    JSON.stringify({x: 1, y: 2}),
    JSON.stringify(new Date()), // ⚠️
    ]
    .forEach(i => console.log(i));

     

    // 이후 배울 Symbol - 직렬화되지 않음
    console.log( JSON.stringify(Symbol('hello')) ); // ⚠️

     

    // 이후 배울 BigInt - 오류 발생
    console.log( JSON.stringify(1n) ); // ⚠️

    ⭐️ 값이 함수인 프로퍼티는 직렬화되지 않음

    const obj = {
    x: 1,
    y: 2,
    z: function () { return this.x + this.y }
    }
    console.log(obj.z())
    const objStr = JSON.stringify(obj);
    console.log(objStr);

     

    const func1 = (a, b) => a + b;
    function func2 () { console.log('HELLO'); }
    const func1Str = JSON.stringify(func1);
    const func2Str = JSON.stringify(func2);
    console.log(func1Str);
    console.log(func2Str);

    💡 2번째 인자: replacer 함수

    • 직렬화될 방식을 지정
    const obj = {
    a: 1,
    b: '2',
    c: 3,
    d: true,
    e: false
    }
    // 1. key와 value 매개변수
    const objStr1 = JSON.stringify(obj, (key, value) => {
    if (key && key < 'a' || key > 'c') {
    // 해당 프로퍼티 생략
    return undefined;
    // ⚠️ 조건에 key && 을 붙이지 않으면 항상 undefined가 반환됨
    // key가 공백('')일 때(value는 객체 자체) undefined를 반환하므로...
    // key와 value를 로그로 출력해보며 확인해 볼 것
    }
    if (typeof value === 'number') {
    return value * 10;
    }
    return value;
    });
    console.log(objStr1);

     

    // 2. 반환한 key의 배열 매개변수
    const objStr2 = JSON.stringify(obj, ['b', 'c', 'd']);
    console.log(objStr2);

    3번째 인자: 인덴트

    const obj = {
    a: 1,
    b: {
    c: 2,
    d: {
    e: 3
    }
    }
    };
    [
    JSON.stringify(obj, null),
    JSON.stringify(obj, null, 1),
    JSON.stringify(obj, null, 2),
    JSON.stringify(obj, null, '\t')
    ]
    .forEach(i => console.log(i));

    객체의 toJSON 프로퍼티

    const obj = {
    x: 1,
    y: 2,
    toJSON: function () {
    return '훗, 나를 직렬화해보겠다는 건가';
    }
    }
    console.log(
    JSON.stringify(obj)
    );



    2. parse - 역직렬화

    [
    JSON.parse('1'),
    JSON.parse('"가나다"'), // ⚠️ 안쪽에 따옴표 포함해야 함
    JSON.parse('true'),
    JSON.parse('null'),
    JSON.parse('[1, 2, 3]'),
    JSON.parse('{"x": 1, "y": 2}') // ⚠️ key도 따옴표로 감싸야 함
    ]
    .forEach(i => console.log(i));

    2번째 인자: receiver 함수

    const objStr = '{"a":1,"b":"ABC","c":true,"d":[1,2,3]}';
    const obj = JSON.parse(objStr, (key, value) => {
    if (key === 'c') {
    // 해당 프로퍼티 생략
    return undefined;
    }
    if (typeof value === 'number') {
    return value * 100;
    }
    return value;
    });
    console.log(obj); // ⚠️ 내부까지 적용(배열 확인해 볼 것)




     

    III. 깊은 복사 deep copy

    ⭐️ JSON을 사용한 깊은 복사

    const obj1 = {
    a: 1,
    b: {
    c: 2,
    d: {
    e: 3,
    f: {
    g: 4
    }
    }
    }
    }
    const obj2 = JSON.parse(JSON.stringify(obj1));
    console.log(obj1);
    console.log(obj2);

     

    obj1.a++;
    obj1.b.c++;
    obj1.b.d.e++;
    obj1.b.d.f.g++;
    console.log(obj1);
    console.log(obj2);

     

    💡 함수, Date, Symbol, BigInt 프로퍼티는 JSON 방식으로는 불가 또는 제한적

    const obj1 = {
    a: 1,
    b: 2,
    c: function () { return this.a + this.b },
    d: new Date(),
    e: Symbol('안녕'),
    // g: 1n // ⚠️ 오류 발생
    }
    const obj2 = JSON.parse(JSON.stringify(obj1));
    console.log(obj1);
    console.log(obj2);



    ⭐️ structuredClone

    • 아직은 일부 브라우저(Web API 형태로) 및 환경에서만 지원
    • JSON 방식보다 빠르고 효율적인 깊은 복사
    • Date와 BigInt 제대로 복사 - 함수와 Symbol은 여전히 불가
    • 👉 MDN 문서 보기
    const obj1 = {
    a: 1,
    b: 2,
    // c: function () { return this.a + this.b },
    d: new Date(),
    // e: Symbol('안녕'),
    g: 1n
    }
    const obj2 = structuredClone(obj1);
    console.log(obj1);
    console.log(obj2);
     
Designed by Tistory.