127

デバッグ用に人間が読める形式で JavaScript データ構造を「きれいに印刷」する方法を見つけようとしています。

JS に保存されているかなり大きくて複雑なデータ構造があり、それを操作するためのコードを記述する必要があります。自分が何をしていて、どこが間違っているのかを突き止めるために、本当に必要なのは、データ構造全体を確認し、UI を介して変更を加えるたびに更新できるようにすることです。

JavaScript のデータ構造を人間が読める文字列にダンプする良い方法を見つけることを除けば、これらすべては自分で処理できます。JSON で十分ですが、適切にフォーマットされ、インデントされている必要があります。通常、これには Firebug の優れた DOM ダンプ機能を使用しますが、構造全体を一度に表示できるようにする必要があり、Firebug ではそれができないようです。

4

16 に答える 16

238

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 ファイル以外は何も必要ありません。どのライブラリなどでも動作します。

于 2008-09-24T23:01:01.387 に答える
33

出力はインデントされていませんが、JS オブジェクトを読み取り可能な形式でダンプする関数を作成しましたが、それを追加するのはそれほど難しくありません。Lua 用に作成した関数からこの関数を作成しました (これははるかに複雑です) このインデントの問題を処理しました。

「シンプル」バージョンは次のとおりです。

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$/, "");
}

再帰呼び出しのある行でインデントを選択し、この後のコメント行を切り替えてスタイルをブレースします。

... 独自のバージョンを作成したようです。これは良いことです。訪問者に選択権があります。

于 2008-09-24T23:06:46.350 に答える
21

以下を使用できます

<pre id="dump"></pre>
<script>
   var dump = JSON.stringify(sampleJsonObject, null, 4); 
   $('#dump').html(dump)
</script>
于 2012-07-23T05:42:35.123 に答える
15

ではFirebugconsole.debug ("%o", my_object)コンソールでクリックしてインタラクティブなオブジェクト エクスプローラーに入ることができます。オブジェクト全体が表示され、ネストされたオブジェクトを展開できます。

于 2008-09-24T22:48:56.660 に答える
12

Node.js の場合は、次を使用します。

util.inspect(object, [options]);

API ドキュメント

于 2011-10-05T18:55:56.683 に答える
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: []
    }
}

また、将来の変更が必要になる可能性がある場合に備えて、ここに Gistとして投稿しました。

于 2011-04-11T05:53:01.537 に答える
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">
]

QUnit (jQuery で使用される単体テスト フレームワーク) は、わずかにパッチが適用されたバージョンの jsDump を使用します。


JSON.stringify() は、場合によっては最良の選択ではありません。

JSON.stringify({f:function(){}}) // "{}"
JSON.stringify(document.body)    // TypeError: Converting circular structure to JSON
于 2010-02-18T22:00:59.473 に答える
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
}
于 2008-09-24T23:37:38.367 に答える
1

これは、Jason Buntingの「UseCrockfordの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;
于 2010-02-18T21:46:56.380 に答える
1

このスレッドでは多くの人がコードを書いており、さまざまな落とし穴について多くのコメントが寄せられています。このソリューションは完全に見え、依存関係のない単一のファイルだったので気に入りました。

ブラウザ

nodejs

それは「箱から出して」動作し、ノードとブラウザの両方のバージョンがあります(おそらくラッパーが異なるだけですが、確認するために掘り下げませんでした)。

ライブラリは整形式の XML、SQL、CSS もサポートしていますが、私はこれらの機能を試していません。

于 2013-03-21T16:00:52.980 に答える
1

JSON.stringify の使用に関する J. Buntings の反応も良かったと思います。余談ですが、YUI を使用している場合は、YUI の JSON オブジェクトを介して JSON.stringify を使用できます。私の場合、HTML にダンプする必要があったため、PhiLho の応答を微調整/切り取り/貼り付けする方が簡単でした。

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;
}
于 2011-03-29T16:24:57.180 に答える
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);
于 2014-08-29T18:29:06.520 に答える
-5

flexjsonには、必要なものが得られる prettyPrint() 関数が含まれています。

于 2008-09-24T22:50:52.457 に答える