자바스크립트 JSON 문자열 변환 (stringify)

원본: Converting Javascript Objects into Strings with JSON.stringify()

JSON 문자열화는 자바스크립트 객체를 애플리케이션 내에서 사용할 수 있는 일반 문자열로 변환하는 작업입니다.

이를 수행하는 방법은 자바스크립트 표준에서 지정한 대로 JSON.stringify() 메소드를 사용하는 것 입니다.

이 메소드는 JSON 문자열을 자바스크립트 객체로 변환하는 JSON.parse() 메소드의 반대 메소드 입니다.

JSON.stringify() 사용 방법

일반적으로 데이터베이스, REST API 등 데이터 저장소에는 자바스크립트를 해석하는 기능이 없습니다.

따라서 해당 자바스크립트 객체를 다른 프로그램에서도 쉽게 읽을 수 있는 형식(문자열)으로 변환해야 합니다.

JSON.stringify() 메소드는 자바스크립트 객체와 이를 저장하는 데이터 소스 사이에 다리 역할을 하여 객체를 key/value 쌍의 일반 문자열로 변환합니다.

문자열은 모든 데이터 저장소에서 보편적으로 사용하는 데이터 타입이기 때문입니다.

일반 JSON 문자열은 다음과 같습니다:

let example1 = '{"a": "b", "c": 1, "d": {"e": 2}}';

이 메소드의 문법 구문은 다음과 같습니다:

JSON.stringify(javascriptObject, replacer, space)

필수 매개변수: javascriptObject

이 메소드는 문자열로 변환할 자바스크립트 객체를 첫 번째 매개변수로 받습니다.

자바스크립트 객체의 리터럴 문자열은 입력하기 번거로우므로 변수로 전달하는 것이 더 간단하고 이해하기 쉽습니다.

최신 자바스크립트는 단순한 데이터를 가지는 모든 것을 객체 타입으로 간주하기 때문에 이 메소드는 숫자나 배열 같이 단순한 구조도 매개변수로 받을 수 있습니다.

let example2a = {
    a: 1,
    b: 2
};

let example2b = JSON.stringify(example2a);

console.log(example2b);
JSON.stringify() 사용 예제

개발자 도구에서 위의 코드를 테스트하고 console.log() 메소드로 문자열화된 JSON 객체를 확인할 수 있습니다.

옵셔널 매개변수: replacer

다음으로 replacer 라는 두 번째 매개변수(옵셔널)를 받습니다.

replacer는 JSON.parse()의 reviver 함수와 비슷합니다. 이는 JSON.stringify()가 자동으로 처리할 수 없는 부분을 처리합니다.

이는 function, undefined, symbol 같은 값을 특정 문자열로 처리할 유일한 방법입니다. 브라우저의 구현에 따라 이 값은 null 이거나 완전히 생략되는 경우도 있습니다.

주로 이 매개변수는 실제 함수를 문자열화하는 경우 scope가 사라지고 제대로 작동하지 않게 되므로 함수를 상용구 문자열로 대체하는 처리를 담당합니다.

function replacer(key, value) {
    if (value typeof "function") {
        return "function";
    }

    return value;
}

옵셔널 매개변수: space

세 번째 매개변수는 space 라는 옵셔널 값 입니다.

문자열 또는 숫자를 받는 이 매개변수는 가독성을 위해 문자열로 변환된 JSON에 삽입되는 공백의 양을 정의합니다.

// 공백이 포함되지 않은 JSON
{"a": "b", "c": 1, "d": {"e": 2}}

// 4개의 공백이 추가된 JSON
{
    "a": "b",
    "c": 1,
    "d":
        {
            "e": 2
        }
}

space 값을 문자열로 정의하든 숫자로 정의하든 가능한 최대 공백 문자의 수는 10개 입니다.

공백 문자열이 10 글자 보다 크면 처음 10 자만 사용됩니다.

또한 1 보다 작은 숫자를 입력하면 공백이 삽입되지 않습니다.

space 매개변수는 replacer 함수를 정의한 경우에만 사용할 수 있습니다.

다음은 메소드 호출 시 자바스크립트 객체인 object와 치환 함수 replacer와 공백의 양을 지정하는 예제입니다:

JSON.stringify(object, replacer, new Number(10));  // 10 spaces
JSON.stringify(object, replacer, new Number(100)); // 10 spaces
JSON.stringify(object, replacer, new Number(-2));  // 0 spaces
JSON.stringify(object, replacer, "     ");         // 5 spaces

JSON.stringify() 특수 상황 처리

에러 처리

JSON.parse()와 마찬가지로 JSON.stringify()도 오류를 발생시키므로 try…catch 문으로 감싸야 합니다.

이 메소드는 두 가지 컨텍스트에서 TypeError를 발생시킵니다. 자바스크립트 객체에서 순환 참조가 발생하거나 자바스크립트 객체에 BigInt가 포함된 경우입니다.

replacer에서는 이러한 오류를 포착하거나 변경할 수 없습니다.

try {
    JSON.stringify(input);
} catch (e) {
    return undefined;
}

나열할 수 없는 속성

이 메소드의 컨텍스트에서 나열 불가능한 속성이란 문자열 변환 시 중요한 정보를 잃을 수 있는 속성입니다.

나열 불가능한 속성에는 function 또는 symbol이 있습니다.

function은 문자열 변경 시 scope가 손실될 수 있기 때문입니다.

symbol은 인코딩, 로케일 차이 등으로 인해 제대로 문자열 변경이 되지 않을 수 있기 때문에 이들은 문자열로 변환할 수 없습니다.

function test() {
    console.log('test');
}

JSON.stringify({ function: test });
JSON.stringify 나열 불가 속성

나열할 수 없는 속성은 일반적으로 대응할 수 있는 문자열이 없기 때문에 앞에서 언급한 것처럼 replacer를 사용하여 상용구 텍스트로 대체할 수 있습니다.

나열 불가능한 속성은 앞에서 언급한 TypeError를 일으키지 않는 한 나머지 자바스크립트 객체를 문자열화하는 작업을 중지시키지 않습니다.

symbol key와 value

JSON 객체가 symbol 객체인 key를 가지는 경우 JSON.stringify() 메소드는 key와 해당 value를 모두 무시합니다.

즉 이와 같은 key/value 쌍은 replacer에서 처리할 수 없기 때문에 문자열 변환 시 포함되지 않는다는 점을 기억해야합니다.

반면 symbol 객체가 JSON 객체의 value인 경우 다른 나열할 수 없는 객체와 마찬가지로 replacer에서 처리할 수 있습니다.

안전하게 JSON.stringify() 사용하기

이 메소드를 안전하게 사용하기 위해서는 함수를 따로 만들어 JSON.stringify()를 실행하고 예외를 처리하도록 코드를 작성해야 합니다.

나열할 수 없는 속성을 처리하기 위해 replacer 함수를 closure 패턴으로 삽입할 수 있습니다.

JSON.stringify()가 제공하는 기능 이외의 문자열 변환을 수행하려면 아래의 예제에서 처럼 replacer 함수를 넣을 수 있습니다.

또한 space 매개변수에 기본 값을 지정할 수도 있습니다.

function safeJsonStringify(json, replacer, space) {
    function defaultReplacer(key, value) {
        if (value typeof "function") { return "function"; }
        if (value typeof "symbol") { return "symbol"; }
        if (typeof value === 'undefined') { return null; }
        if (replacer !== undefined) { replacer(); }
        return value;
    }

    try {
        let defaultSpace = 4;

        if (space !== undefined) { defaultSpace = space; }

        let jsonString = JSON.stringify(json, defaultReplacer, defaultSpace);
    } catch(e) {
        return null;
    }
}

정리

JSON.stringify()는 JSON.parse()와 비슷하게 작동합니다.

이 두가지 메소드는 자바스크립트 객체를 저장 가능한 형식으로 전송하고 다시 되돌릴 수 있는 완벽한 솔루션을 제공합니다.

관련 글

자바스크립트 튜토리얼