it-swarm.com.de

JavaScript-Datenformatierung / hübscher Drucker

Ich versuche einen Weg zu finden, pretty print eine JavaScript-Datenstruktur in lesbarer Form zum Debuggen.

Ich habe eine ziemlich große und komplizierte Datenstruktur, die in JS gespeichert ist, und ich muss Code schreiben, um sie zu manipulieren. Um herauszufinden, was ich tue und wo ich falsch liege, muss ich in der Lage sein, die Datenstruktur in ihrer Gesamtheit zu sehen und zu aktualisieren, wann immer ich Änderungen über die Benutzeroberfläche vornehme.

All diese Dinge kann ich selbst erledigen, abgesehen davon, dass ich eine gute Möglichkeit gefunden habe, eine JavaScript-Datenstruktur in eine für Menschen lesbare Zeichenfolge zu schreiben. JSON würde es tun, aber es muss wirklich gut formatiert und eingerückt sein. Normalerweise würde ich dafür Firebugs hervorragendes DOM-Dumping-Zeug verwenden, aber ich muss wirklich in der Lage sein, die gesamte Struktur auf einmal zu sehen, was in Firebug nicht möglich zu sein scheint.

Anregungen sind willkommen.

Danke im Voraus.

123
Dan

Ich habe eine Funktion geschrieben, um ein JS-Objekt in lesbarer Form zu sichern, obwohl die Ausgabe nicht eingerückt ist, aber es sollte nicht zu schwer sein, dies hinzuzufügen: Ich habe diese Funktion aus einer für Lua erstellten gemacht (die viel komplexer ist) ), der dieses Einrückungsproblem behandelt hat.

Hier ist die "einfache" Version:

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;
}

Ich werde versuchen, es ein bisschen zu verbessern.
Hinweis 1: Um es zu benutzen, mache od = DumpObject(something) und benutze od.dump. Gewunden, weil ich den Wert len ​​(Anzahl der Elemente) auch für einen anderen Zweck haben wollte. Es ist trivial, die Funktion nur die Zeichenfolge zurückgeben zu lassen.
Hinweis 2: Es werden keine Schleifen in Referenzen verarbeitet.

EDIT

Ich habe die eingerückte Version gemacht.

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

Wählen Sie Ihre Einrückung in der Zeile mit dem rekursiven Aufruf aus und ändern Sie den Stil, indem Sie die kommentierte Zeile nach dieser Zeile verschieben.

... Ich sehe, Sie haben Ihre eigene Version erstellt, was gut ist. Besucher haben die Wahl.

30
PhiLho

Verwenden Sie Crockfords JSON.stringify wie folgt:

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...

Die Variable text würde folgendermaßen aussehen:

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

Dies erfordert übrigens nichts weiter als diese JS-Datei - sie funktioniert mit jeder Bibliothek usw.

228
Jason Bunting

Sie können Folgendes verwenden

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

Wenn Sie in Firebug nur auf console.debug ("%o", my_object) klicken, können Sie in der Konsole darauf klicken und einen interaktiven Objekt-Explorer aufrufen. Es zeigt das gesamte Objekt und lässt Sie verschachtelte Objekte erweitern.

15
John Millikin

Verwenden Sie für Node.js:

util.inspect(object, [options]);

API-Dokumentation

11
Davem M

Für diejenigen, die nach einer großartigen Möglichkeit suchen, Ihr Objekt zu sehen, überprüfen Sie prettyPrint.js

Erstellt eine Tabelle mit konfigurierbaren Ansichtsoptionen, die irgendwo in Ihrem Dokument gedruckt werden soll. Besser als im console.

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

enter image description here

9
RaphaelDDL

Ich programmiere in Rhino und war mit keiner der hier veröffentlichten Antworten zufrieden. Also habe ich meinen eigenen hübschen Drucker geschrieben:

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)
}

Die Ausgabe sieht folgendermaßen aus:

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: []
    }
}

Ich habe es auch als Gist hier gepostet, falls zukünftige Änderungen erforderlich sein sollten.

6
knowtheory

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')
])

wird

[
   [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 (von jQuery verwendetes Unit-Testing-Framework) mit einer leicht gepatchten Version von jsDump.


JSON.stringify () ist in manchen Fällen nicht die beste Wahl.

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

Als ich PhiLhos Führung übernahm (vielen Dank :)), schrieb ich letztendlich meine eigene, da ich seine nicht dazu bringen konnte, das zu tun, was ich wollte. Es ist ziemlich rau und fertig, aber es macht den Job, den ich brauche. Vielen Dank für die hervorragenden Vorschläge.

Es ist kein brillanter Code, ich weiß, aber für das, was es wert ist, ist es hier. Jemand könnte es nützlich finden:

// 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
Dan

Viele Leute schreiben Code in diesen Thread, mit vielen Kommentaren über verschiedene Fallstricke. Ich mochte diese Lösung, weil sie vollständig schien und eine einzelne Datei ohne Abhängigkeiten war.

Browser

nodejs

Es funktionierte "out of the box" und hat sowohl Node- als auch Browser-Versionen (vermutlich nur verschiedene Wrapper, aber ich habe Dig nicht bestätigt).

Die Bibliothek unterstützt auch das schöne Drucken von XML, SQL und CSS, aber ich habe diese Funktionen nicht ausprobiert.

1
mm2001

Ich fand, dass J. Buntings Antwort auf die Verwendung von JSON.stringify auch gut war. Abgesehen davon können Sie JSON.stringify über YUIs JSON-Objekt verwenden, wenn Sie zufällig YUI verwenden. In meinem Fall musste ich nach HTML ausgeben, damit es einfacher war, die PhiLho-Antwort zu optimieren, auszuschneiden und einzufügen.

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
GTM

Dies ist eigentlich nur ein Kommentar zu Jason Bunting '' Use Crockford's JSON.stringify '', aber ich konnte dieser Antwort keinen Kommentar hinzufügen.

Wie in den Kommentaren erwähnt, funktioniert JSON.stringify mit der Prototype-Bibliothek (www.prototypejs.org) nicht gut. Es ist jedoch ziemlich einfach, ein gutes Zusammenspiel zu erzielen, indem die Array.prototype.toJSON-Methode, die der Prototyp hinzufügt, vorübergehend entfernt wird. Führen Sie Crockfords stringify () aus und setzen Sie es dann wie folgt zurück:

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

Ein einfaches Verfahren zum Drucken der Elemente als Zeichenfolgen:

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
aliteralmind

Meine NeatJSON Bibliothek enthält sowohl Ruby als auch JavaScript-Versionen . Es ist frei verfügbar unter einer (permissiven) MIT Lizenz. Sie können eine Online-Demo/einen Online-Konverter unter folgender Adresse anzeigen:
http://phrogz.net/JS/neatjson/neatjson.html

Einige Funktionen (alle optional):

  • Auf eine bestimmte Breite wickeln; Wenn ein Objekt oder ein Array in die Zeile passen kann, wird es in einer Zeile beibehalten.
  • Richten Sie die Doppelpunkte für alle Schlüssel in einem Objekt aus.
  • Sortieren Sie die Schlüssel zu einem Objekt alphabetisch.
  • Formatieren Sie Gleitkommazahlen auf eine bestimmte Anzahl von Dezimalstellen.
  • Verwenden Sie beim Zeilenumbruch eine "kurze" Version, bei der die öffnenden/schließenden Klammern für Arrays und Objekte in derselben Zeile stehen wie der erste/letzte Wert.
  • Kontrollieren Sie das Leerzeichen für Arrays und Objekte auf granulare Weise (in eckigen Klammern, vor/nach Doppelpunkten und Kommas).
  • Funktioniert im Webbrowser und als Node.js-Modul.
0
Phrogz