JavaScript 데이터 형식화 / 예쁜 프린터


124

pretty print디버깅을 위해 사람이 읽을 수있는 형식의 JavaScript 데이터 구조에 대한 방법을 찾으려고합니다 .

JS에 저장되는 다소 크고 복잡한 데이터 구조가 있으며이를 조작하기 위해 코드를 작성해야합니다. 내가하고있는 일과 내가 잘못되고있는 부분을 파악하기 위해 내가 정말로 필요한 것은 데이터 구조 전체를 볼 수 있고 UI를 통해 변경할 때마다 업데이트하는 것입니다.

자바 스크립트 데이터 구조를 사람이 읽을 수있는 문자열로 덤프하는 좋은 방법을 찾는 것 외에는이 모든 것을 직접 처리 할 수 ​​있습니다. JSON도 가능하지만 실제로 형식이 잘 지정되고 들여 쓰기가 필요합니다. 저는 보통 Firebug의 뛰어난 DOM 덤핑 도구를 사용하지만, Firebug에서는 불가능한 것처럼 전체 구조를 한 번에 볼 수 있어야합니다.

어떤 제안이라도 환영합니다.

미리 감사드립니다.


답변 수정 알림을 받았는지 확실하지 않습니다. 그래서 나는 내 자신의 들여 쓰기 덤프 버전을 추가했음을 알리기 위해이 코멘트를 작성합니다. :-)
PhiLho

참고 : JSON.stringify () 답변은 'the'답변으로 받아 들여지지는 않지만 매우 유용 해 보입니다.
GuruM 2013

: 당신은 nodedump 사용하여 개체의 시각적, 직관적 인 출력을 얻을 수 github.com/ragamufin/nodedump
ragamufin

답변:


31

출력이 들여 쓰기되지는 않았지만 읽을 수있는 형태로 JS 객체를 덤프하는 함수를 작성했지만 추가하기가 너무 어렵지 않아야합니다. )는이 들여 쓰기 문제를 처리했습니다.

다음은 "간단한"버전입니다.

function DumpObject(obj)
{
  var od = new Object;
  var result = "";
  var len = 0;

  for (var property in obj)
  {
    var value = obj[property];
    if (typeof value == 'string')
      value = "'" + value + "'";
    else if (typeof value == 'object')
    {
      if (value instanceof Array)
      {
        value = "[ " + value + " ]";
      }
      else
      {
        var ood = DumpObject(value);
        value = "{ " + ood.dump + " }";
      }
    }
    result += "'" + property + "' : " + value + ", ";
    len++;
  }
  od.dump = result.replace(/, $/, "");
  od.len = len;

  return od;
}

나는 그것을 조금 개선 할 것입니다.
참고 1 : 사용하려면 od = DumpObject(something)od.dump를 수행 하고 사용하십시오. 다른 목적을 위해 len 값 (항목 수)도 원했기 때문에 복잡했습니다. 함수가 문자열 만 반환하도록 만드는 것은 간단합니다.
참고 2 : 참조의 루프를 처리하지 않습니다.

편집하다

들여 쓰기 버전을 만들었습니다.

function DumpObjectIndented(obj, indent)
{
  var result = "";
  if (indent == null) indent = "";

  for (var property in obj)
  {
    var value = obj[property];
    if (typeof value == 'string')
      value = "'" + value + "'";
    else if (typeof value == 'object')
    {
      if (value instanceof Array)
      {
        // Just let JS convert the Array to a string!
        value = "[ " + value + " ]";
      }
      else
      {
        // Recursive dump
        // (replace "  " by "\t" or something else if you prefer)
        var od = DumpObjectIndented(value, indent + "  ");
        // If you like { on the same line as the key
        //value = "{\n" + od + "\n" + indent + "}";
        // If you prefer { and } to be aligned
        value = "\n" + indent + "{\n" + od + "\n" + indent + "}";
      }
    }
    result += indent + "'" + property + "' : " + value + ",\n";
  }
  return result.replace(/,\n$/, "");
}

재귀 호출이있는 줄에서 들여 쓰기를 선택하고이 줄 뒤에 주석 처리 된 줄을 전환하여 스타일을 중괄호로 지정합니다.

... 당신이 자신의 버전을 채찍질 한 것을 보았습니다. 방문자는 선택할 수 있습니다.


1
나는 좋아한다;) 제대로 작동하도록 할 수 없지만 괜찮다면, 나는 뻔뻔하게 개념을 훔쳐서 내 자신의 글을 쓸 것이다 :)
Dan

2
(JSON.stringify 메소드 Jason이 제안한 것과 비교할 때)이 접근 방식의 한 가지 단점은 객체 배열을 제대로 표시하지 않는다는 것입니다. 객체 배열이 있으면 [object Object]로 표시됩니다.
라이언

@Ryan : 브라우저의 기본 개체를 의미합니까? 예, 내 코드를 돌아 보면 주석이 추가 된 것을 보았습니다. // 하나의 필드가 객체이면 너무 나쁩니다 ... :-P 여기에서 테스트해도 괜찮습니다 ... 사용자가 만든 구조를 덤프해도 괜찮습니다. 더 강력한 것이 필요한 경우 아래에 대안이 있습니다.
PhiLho 2010 년

나는 이것을 사용할 수 없습니다. 일부 json 데이터를 덤프하려고하면 무한 루프가 발생합니다.
neoneye

1
@RaphaelDDL & PhiLho-최대 호출 스택 크기는 작은 개체에서도 트리거 될 수 있습니다. 하나는 자신에 대한 속성 참조가 있습니다. 이러한 참조는이 함수와 함께 무한 루프를 발생시킵니다.
skibulk

233

다음 과 같이 Crockford의 JSON.stringify를 사용하십시오 .

var myArray = ['e', {pluribus: 'unum'}];
var text = JSON.stringify(myArray, null, '\t'); //you can specify a number instead of '\t' and that many spaces will be used for indentation...

변수 text는 다음과 같습니다.

[
  "e",
   {
      "pluribus": "unum"
   }
]

그건 그렇고, JS 파일 이상이 필요하지 않습니다-모든 라이브러리 등에서 작동합니다.


5
이것은 거의 확실히 당신이 얻을 최고의 대답입니다. 프로그래머가 아닌 사람 4 명 또는 5 명에게 JSON.stringified 데이터 구조를 읽고 편집하고 구성 파일에 광범위하게 사용하도록 가르쳤습니다.
Joel Anair

1
이상하게도 문제가 발생할 수 있습니다. 전역 네임 스페이스에 "JSON"이라는 이름이 도입되어 문제가 발생할 수 있습니다. 충돌이 있는지 확인하기 위해 이것을 추가 하기 전에 "JSON"에 대한 네임 스페이스를 확인하십시오 .
Jason Bunting

1
글쎄, 프로토 타입은 그렇게 사악하다 ...;)
Jason Bunting

7
이에 대한 업데이트는 Firefox 3.5 이상인 JSON.stringify가 내장되어 있습니다. ( developer.mozilla.org/En/Using_JSON_in_Firefox ), 디버깅 목적으로 JSON 객체를 보려는 경우 추가 JS 종속성없이 수행 할 수 있습니다.
Greg Bernhardt

3
Chrome에서도 마찬가지입니다. 그러나 JSON.stringify는 순환 데이터 JSON.stringify((function(){var x = []; x.push(x); return x})())및 기타 여러 종류의 객체에서 실패 합니다 JSON.stringify(/foo/).
Kragen Javier Sitaker 2011 년

21

다음을 사용할 수 있습니다.

<pre id="dump"></pre>
<script>
   var dump = JSON.stringify(sampleJsonObject, null, 4); 
   $('#dump').html(dump)
</script>

15

에서가 Firebug, 당신은 단지 경우에 console.debug ("%o", my_object)당신은 콘솔에서 클릭하고 대화 형 객체 탐색기를 입력 할 수 있습니다. 전체 개체를 표시하고 중첩 된 개체를 확장 할 수 있습니다.


1
문제는 '최상위'개체 만 표시된다는 것입니다. 수십 개의 중첩 된 개체가 있고, 전체 내용을 한 번에 볼 수 있어야하고, 중요한 것은 어디에서 변경되고 있는지 확인해야한다는 것입니다. 따라서 Firebug는이 경우 실제로 작동하지 않습니다.
Dan

(예, 클릭하여 확장 할 수 있다는 것을 알고 있지만 데이터를 덤프 할 때마다 10 개 정도의 링크를 클릭하는 것이 지금하고있는 작업입니다. 진행 속도가 매우 느립니다.)
Dan

1
이것은 Chrome에서도 작동합니다 (따라서 아마도 Safari에서).
Kragen Javier Sitaker 2011 년


9

개체를 보는 멋진 방법을 찾는 사람들은 prettyPrint.js 를 확인하세요.

문서의 어딘가에 인쇄 할 구성 가능한보기 옵션이있는 표를 만듭니다. 더 나은는보다 볼 수 있습니다 console.

var tbl = prettyPrint( myObject, { /* options such as maxDepth, etc. */ });
document.body.appendChild(tbl);

여기에 이미지 설명 입력


6

나는 프로그래밍 Rhino중이며 여기에 게시 된 답변에 만족하지 않았습니다. 그래서 나는 내 자신의 예쁜 프린터를 작성했습니다.

function pp(object, depth, embedded) { 
  typeof(depth) == "number" || (depth = 0)
  typeof(embedded) == "boolean" || (embedded = false)
  var newline = false
  var spacer = function(depth) { var spaces = ""; for (var i=0;i<depth;i++) { spaces += "  "}; return spaces }
  var pretty = ""
  if (      typeof(object) == "undefined" ) { pretty += "undefined" }
  else if ( typeof(object) == "boolean" || 
            typeof(object) == "number" ) {    pretty += object.toString() } 
  else if ( typeof(object) == "string" ) {    pretty += "\"" + object + "\"" } 
  else if (        object  == null) {         pretty += "null" } 
  else if ( object instanceof(Array) ) {
    if ( object.length > 0 ) {
      if (embedded) { newline = true }
      var content = ""
      for each (var item in object) { content += pp(item, depth+1) + ",\n" + spacer(depth+1) }
      content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
      pretty += "[ " + content + "\n" + spacer(depth) + "]"
    } else { pretty += "[]" }
  } 
  else if (typeof(object) == "object") {
    if ( Object.keys(object).length > 0 ){
      if (embedded) { newline = true }
      var content = ""
      for (var key in object) { 
        content += spacer(depth + 1) + key.toString() + ": " + pp(object[key], depth+2, true) + ",\n" 
      }
      content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
      pretty += "{ " + content + "\n" + spacer(depth) + "}"
    } else { pretty += "{}"}
  }
  else { pretty += object.toString() }
  return ((newline ? "\n" + spacer(depth) : "") + pretty)
}

출력은 다음과 같습니다.

js> pp({foo:"bar", baz: 1})
{ foo: "bar",
  baz: 1
}
js> var taco
js> pp({foo:"bar", baz: [1,"taco",{"blarg": "moo", "mine": "craft"}, null, taco, {}], bleep: {a:null, b:taco, c: []}})
{ foo: "bar",
  baz: 
    [ 1,
      "taco",
      { blarg: "moo",
        mine: "craft"
      },
      null,
      undefined,
      {}
    ],
  bleep: 
    { a: null,
      b: undefined,
      c: []
    }
}

또한 향후 변경이 필요할 수 있도록 여기요점 으로 게시했습니다 .


7
그것은 꽤 프린터 될 수 있지만, 코드는 실제로 : 아주 예쁜 보지 않는다
XION

3

jsDump

jsDump.parse([
    window,
    document,
    { a : 5, '1' : 'foo' },
    /^[ab]+$/g,
    new RegExp('x(.*?)z','ig'),
    alert, 
    function fn( x, y, z ){
        return x + y; 
    },
    true,
    undefined,
    null,
    new Date(),
    document.body,
    document.getElementById('links')
])

된다

[
   [Window],
   [Document],
   {
      "1": "foo",
      "a": 5
   },
   /^[ab]+$/g,
   /x(.*?)z/gi,
   function alert( a ){
      [code]
   },
   function fn( a, b, c ){
      [code]
   },
   true,
   undefined,
   null,
   "Fri Feb 19 2010 00:49:45 GMT+0300 (MSK)",
   <body id="body" class="node"></body>,
   <div id="links">
]

약간 패치 된 jsDump 버전을 사용하는 QUnit (jQuery에서 사용하는 단위 테스트 프레임 워크).


JSON.stringify ()는 어떤 경우에는 최선의 선택이 아닙니다.

JSON.stringify({f:function(){}}) // "{}"
JSON.stringify(document.body)    // TypeError: Converting circular structure to JSON

2

PhiLho의 리드를 받아 (정말 감사합니다 :)) 내가 원하는 것을 그가 할 수 없었기 때문에 나는 결국 내 자신의 글을 작성했습니다. 꽤 거칠고 준비가되어 있지만 필요한 일을합니다. 훌륭한 제안에 감사드립니다.

훌륭한 코드는 아니지만, 그만한 가치는 여기 있습니다. 누군가 유용하다고 생각할 수 있습니다.

// Usage: dump(object)
function dump(object, pad){
    var indent = '\t'
    if (!pad) pad = ''
    var out = ''
    if (object.constructor == Array){
        out += '[\n'
        for (var i=0; i<object.length; i++){
            out += pad + indent + dump(object[i], pad + indent) + '\n'
        }
        out += pad + ']'
    }else if (object.constructor == Object){
        out += '{\n'
        for (var i in object){
            out += pad + indent + i + ': ' + dump(object[i], pad + indent) + '\n'
        }
        out += pad + '}'
    }else{
        out += object
    }
    return out
}

1
그건 그렇고, 가능하더라도 세미콜론없이 줄을 끝내면 안됩니다. 또한 __ if (! pad) pad = ''__를 수행하는 표준 방법은 다음과 같습니다. __ pad = (pad || '') __
Jason Bunting

나는 if (! foo) foo = ... vs foo = (foo || ...)에 대한 당신의 요점을 가지고 있지만, 모든 줄을 세미콜론으로 끝내는 이유는 무엇입니까?
Dan

1
그렇지 않으면 코드를 쉽게 축소 할 수 없다는 것은 말할 것도없이 언어의 불쾌한 특이점에 부딪 힐 것입니다 (사용하는 축소자가 세미콜론을 삽입하기에 충분하지 않는 한). 자세한 내용은 stackoverflow.com/questions/42247 을 참조하십시오.
Jason Bunting

1
if (! pad) pad = ''; pad = (pad || '')보다 저렴하고 유연하며 읽기 쉽습니다. 비록 분량이지만. 해당 양식을 고집하는 경우 외부 괄호를 제거하십시오. 패드 = 패드 || ''; 세미콜론의 3 가지 이유 : JS는 끝줄 세미콜론을 생략하면 오류가 발생한다는 것을 알게되면 자동 삽입됩니다. 1) 이것은 직접 추가하는 것보다 약간 느리며 2) 다음 줄이 결합 되어도 오류가 발생하지 않을 때 오류가 발생할 수 있습니다. 3) 코드가 축소되는 것을 방지합니다.
SamGoody

1

이것은 실제로 Jason Bunting의 "Use Crockford 's JSON.stringify"에 대한 주석 일 뿐이지 만 그 대답에 주석을 추가 할 수 없었습니다.

주석에서 언급했듯이 JSON.stringify는 Prototype (www.prototypejs.org) 라이브러리와 잘 작동하지 않습니다. 그러나 프로토 타입이 추가하는 Array.prototype.toJSON 메서드를 일시적으로 제거하고 Crockford의 stringify ()를 실행 한 다음 다음과 같이 다시 넣어두면 함께 잘 작동하도록하는 것은 매우 쉽습니다.

  var temp = Array.prototype.toJSON;
  delete Array.prototype.toJSON;
  $('result').value += JSON.stringify(profile_base, null, 2);
  Array.prototype.toJSON = temp;

1

JSON.stringify 사용에 대한 J. Buntings 응답도 좋다고 생각했습니다. 제쳐두고 YUI를 사용하는 경우 YUI JSON 객체를 통해 JSON.stringify를 사용할 수 있습니다. 제 경우에는 PhiLho 응답을 조정 / 잘라 내기 / 붙여 넣기하는 것이 더 쉬웠 기 때문에 HTML로 덤프해야했습니다.

function dumpObject(obj, indent) 
{
  var CR = "<br />", SPC = "&nbsp;&nbsp;&nbsp;&nbsp;", result = "";
  if (indent == null) indent = "";

  for (var property in obj)
  {
    var value = obj[property];

    if (typeof value == 'string')
    {
      value = "'" + value + "'";
    }
    else if (typeof value == 'object')
    {
      if (value instanceof Array)
      {
        // Just let JS convert the Array to a string!
        value = "[ " + value + " ]";
      }
      else
      {
        var od = dumpObject(value, indent + SPC);
        value = CR + indent + "{" + CR + od + CR + indent + "}";
      }
    }
    result += indent + "'" + property + "' : " + value + "," + CR;
  }
  return result;
}

1

이 스레드에서 많은 사람들이 코드를 작성하고 다양한 문제에 대한 많은 의견을 남깁니다. 이 솔루션은 완전 해 보였고 종속성이없는 단일 파일이기 때문에 마음에 들었습니다.

브라우저

nodejs

그것은 "즉시"작동했고 노드와 브라우저 버전을 모두 가지고 있습니다 (아마도 다른 래퍼 일 뿐이지 만 확인을 위해 파헤 치지 않았습니다).

라이브러리는 또한 예쁜 인쇄 XML, SQL 및 CSS를 지원하지만 이러한 기능을 사용해 보지 않았습니다.


0

요소를 문자열로 인쇄하는 간단한 방법 :

var s = "";
var len = array.length;
var lenMinus1 = len - 1
for (var i = 0; i < len; i++) {
   s += array[i];
   if(i < lenMinus1)  {
      s += ", ";
   }
}
alert(s);

0

NeatJSON 라이브러리에는 Ruby 및 JavaScript 버전 이 모두 있습니다 . (허용) MIT 라이선스에 따라 무료로 사용할 수 있습니다. 다음 사이트에서 온라인 데모 / 변환기를 볼 수 있습니다.
http://phrogz.net/JS/neatjson/neatjson.html

일부 기능 (모두 선택 사항) :

  • 특정 너비로 ​​감싸십시오. 객체 또는 배열이 선에 맞을 수 있으면 한 행에 유지됩니다.
  • 개체의 모든 키에 대해 콜론을 정렬합니다.
  • 객체의 키를 알파벳순으로 정렬합니다.
  • 부동 소수점 숫자를 특정 소수 자릿수로 포맷합니다.
  • 줄 바꿈 할 때 배열 및 개체의 여는 / 닫는 대괄호를 첫 번째 / 마지막 값과 같은 줄에 배치하는 '짧은'버전을 사용하십시오.
  • 배열 및 개체의 공백을 세부적으로 제어합니다 (괄호 내부, 콜론 및 쉼표 앞 / 뒤).
  • 웹 브라우저 및 Node.js 모듈에서 작동합니다.

-5

flexjson 에는 원하는 것을 제공 할 수있는 prettyPrint () 함수가 포함되어 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.