Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

JSON 객체를 String으로 변환하기

전에 JSON Text를 JSON Object로 변환하기라는 포스팅을 올린적이 있는데 sopp님이 "반대로 JSON Object를 JSON Text로 변환할 수 있는 방법이 있는지 궁금합니다"라는 댓글을 주셨습니다. JSON객체를 스트링으로 변환할 일이 뭐가 있을까 생각해봤는데 저로써는 로그등을 위해서 찍어보는 용도로 밖에는 생각이 안나더군요. 어쨌든 질문을 테스트 해보다 보니 생각했던거랑은 다른것도 있고 해서 포스팅으로 남깁니다.

이전 포스팅과 동일하게 아래와 같은 JSON객체가 있다고 하겠습니다.

{ id:'Outsider', sex:'male' }

JSON객체를 출력해 보겠습니다.


var obj = { "id":"outsider", "sex":"male" };
alert(obj); // [object Object]
alert(typeof obj); // object

객체라는 것만 알 수 있고 내용을 알 수가 없습니다.(console.log(obj)로 찍으면 Firebug에서 똑똑하게도  Object id=outsider sex=male라고 찍어줍니다. IE8용 콘솔은 alert와 똑같이 찍어주는군요. )



var obj = '{ "id":"outsider", "sex":"male" }';
alert(obj); // { "id":"outsider", "sex":"male" }
alert(typeof obj); // string


이번에는 스트링 객체로 만들어서 그냥 찍어보았습니다. 스트링이기 때문에 그대로 나오는군요. 당연한 결과로 보입니다.

스트링 변환할 때 가장 쉽게 생각할수 있는데 문자열을 이어붙히는 것입니다. 자바스크립트는 형타입이 없기 때문에 문자열을 이어붙힘으로써 쉽게 String으로 만들 수 있습니다.


var obj = { "id":"outsider", "sex":"male" };
obj = obj + ""
alert(obj); // [object Object]
alert(typeof obj); // string

type은 string으로 변경되었지만 객체 자체를 출력하니까 스트링의 내용이 찍히지 않고 Object가 찍혀버립니다. 원래 스트링이었던 객체와는 다르게 동적하는군요. 자바스크립트 프레임워크같은 경우는 사용하기에도 유용하지만 이런 경우에 소스 참고하기에도 유용합니다. (머리좋은 놈들은 어떻게 했나 보는거죠 ㅎ)

prototype.js에는 toJSON()이라는 함수가 있고 JSON객체를 String으로 만들어주는 기능을 가지고 있습니다. 그래서 toJSON의 소스를 열어보았습니다.


toJSON: function(object) {
    var type = typeof object;
    switch (type) {
        case 'undefined':
        case 'function':
        case 'unknown': return;
        case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
        var value = Object.toJSON(object[property]);
        if (!Object.isUndefined(value))
            results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
},

위처럼 정의되어 있습니다. 12라인 까지는 JSON객체가 아닌 객체로 들어왔을때의 예외처리라고 할 수 있을듯 합니다. 14라인 부터가 실제 스트링으로 만들어 줍니다. prototype.js내에서 각 객체에도 toJSON이 추가되어 있기 때문에 내부에서도 toJSON()을 여러번 쓰고 있습니다. toJSON때문에 좀 복잡해 보이지만 실제로는 간단하다고 할 수 있습니다. 전달받은 JSON객체를 루프돌면서 이름으로 값을 가져오고 이름과 값을 array에 넣은 나음에 나중에 콤마로 join시켜 버린것입니다. 문자열을 +로 이어붙히지 않고 array를 이용할 경우 속도차이가 많이 나죠.


function JSONtoString(object) {
    var results = [];
    for (var property in object) {
        var value = object[property];
        if (value)
            results.push(property.toString() + ': ' + value);
        }
                
        return '{' + results.join(', ') + '}';
}

prototype.js를 안쓰시는 분들이 요즘은 많아서 prototype.js용 소스를 걷어버렸습니다.(걷으면서 예외처리도 같이 걷었군요. 그런부분까지 신경쓰긴 좀 귀찮아서.. ㅎ 말 그대로 JSON객체가 string으로 되도록...


var obj = { "id":"outsider", "sex":"male" };
obj = JSONtoString(obj);
alert(obj); // {id: outsider, sex: male}
alert(typeof obj); // string

따옴표는 빠져서 나오는군요... 나중에 다시 JSON객체로 변환할 때 엄격하게 체킹하려면 따옴표 있어야 되는거 아닌가 싶은 생각도 들지만(문법에는 "가 있는걸로...) 그런 추가는 별로 어렵지 않을것 같아서 여기까지만 정리합니다.


ps) 2010.08.11
간단한 JSON에 대한 처리만 고려했던 부분인데 궁금이님의 댓글로 다시 보니 JSON 포맷에는 value부분에 JSON외에도 많은 타입이 들어갈 수 있기 때문에 모든 JSON에 대한 처리를 해주려면 위에 작성한 메서드 만으로는 부족합니다. prototype.js의 경우에는 기본객체들을 확장하기 때문에 타입별로 toJSON 메서드를 제공하여 적절히 변환가능하도록 한 것으로 보입니다.

JSON사이트
에서는 json2.js라는 JSON관련 처리를 위한 공식 메서드를 제공하고 있는데 이곳에서 JSON객체를 String으로 변환하는 JSON.stringify() 메서드를 제공하고 있고 이것을 사용하면 모든 타입에 대응한 JSON객체를 String으로 변환할수 있습니다.
2009/12/03 09:54 2009/12/03 09:54