Question

J'essaie de trouver un moyen de imprimer une structure de données JavaScript sous une forme lisible par l'homme pour le débogage.

JS stocke une structure de données plutôt volumineuse et compliquée et j'ai besoin d'écrire du code pour le manipuler. Afin de comprendre ce que je fais et ce qui ne va pas, je dois avant tout pouvoir visualiser la structure de données dans son intégralité et la mettre à jour chaque fois que je modifie l'interface utilisateur.

Tout ce que je peux gérer moi-même, mis à part le fait de trouver un bon moyen de convertir une structure de données JavaScript en une chaîne lisible par l'homme. JSON ferait l'affaire, mais il doit vraiment être bien formaté et mis en retrait. Pour ce faire, j'utilise habituellement l'excellent logiciel DOM de Firebug, mais je dois vraiment pouvoir visualiser l'ensemble de la structure à la fois, ce qui ne semble pas possible dans Firebug.

Toutes les suggestions sont les bienvenues.

Merci d'avance.

Était-ce utile?

La solution

J'ai écrit une fonction pour vider un objet JS sous une forme lisible, bien que la sortie ne soit pas indentée, mais il ne devrait pas être trop difficile de l'ajouter: j'ai créé cette fonction à partir de celle que j'ai faite pour Lua (qui est beaucoup plus complexe) qui traitait ce problème d'indentation.

Voici le " simple " 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;
}

Je vais chercher à l'améliorer un peu.
Note 1: Pour l'utiliser, faites od = DumpObject (quelque chose) et utilisez od.dump. Convolué parce que je voulais aussi la valeur len (nombre d'éléments) à une autre fin. Il est trivial de faire en sorte que la fonction ne renvoie que la chaîne.
Note 2: il ne gère pas les boucles dans les références.

MODIFIER

J'ai créé la version en retrait.

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

Choisissez l’indentation sur la ligne avec l’appel récursif et vous consolidez le style en changeant la ligne commentée après celle-ci.

... je vois que vous avez préparé votre propre version, ce qui est bien. Les visiteurs auront le choix.

Autres conseils

Vous pouvez utiliser les éléments suivants

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

Dans Firebug , si vous venez de console.debug ("% o", mon_objet) , vous pouvez cliquer dessus dans la console et entrer dans un explorateur d'objets interactif. Il affiche l'objet entier et vous permet de développer des objets imbriqués.

Pour ceux qui recherchent un moyen génial de voir votre objet, consultez prettyPrint.js

Crée un tableau avec des options d'affichage configurables à imprimer quelque part sur votre document. Mieux vaut regarder que dans la console .

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

entrer la description de l'image ici

Je programme dans Rhino et aucune des réponses publiées ici. J'ai donc écrit ma propre jolie imprimante:

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

La sortie ressemble à ceci:

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

Je l'ai également publiée en tant que Gist ici pour toute modification future qui pourrait être nécessaire.

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

devient

[
   [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 (infrastructure de test unitaire utilisée par jQuery) avec une version légèrement corrigée de jsDump.

JSON.stringify () n'est pas le meilleur choix dans certains cas.

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

Prenant l'exemple de PhiLho (merci beaucoup :)), j'ai fini par écrire le mien car je ne pouvais pas le faire faire ce que je voulais. C'est assez difficile et prêt, mais il fait le travail dont j'ai besoin. Merci à tous pour vos excellentes suggestions.

Ce n’est pas un code brillant, je le sais, mais voici ce qu’il vaut. Quelqu'un pourrait le trouver utile:

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

Ceci est vraiment juste un commentaire sur "Utilisez JSON.stringify de Jock.stringify" de Jason Bunting, mais je n'ai pas pu ajouter de commentaire à cette réponse.

Comme indiqué dans les commentaires, JSON.stringify ne fonctionne pas bien avec la bibliothèque Prototype (www.prototypejs.org). Cependant, il est assez facile de les faire bien jouer en supprimant temporairement la méthode Array.prototype.toJSON ajoutée par le prototype, exécutez stringify () de Crockford, puis remettez-le comme ceci:

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

Je pensais que la réponse de J. Buntings à l’utilisation de JSON.stringify était également bonne. De plus, vous pouvez utiliser JSON.stringify via l’objet JSON YUIs si vous utilisez YUI. Dans mon cas, j’avais besoin de passer au format HTML, il était donc plus facile de modifier / couper / coller la réponse de 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;
}

Beaucoup de gens ont écrit du code dans ce fil, avec de nombreux commentaires sur divers pièges. J'ai aimé cette solution car elle semblait complète et constituait un seul fichier sans dépendance.

navigateur

nodejs

Cela a fonctionné "hors de la boîte" et possède à la fois des versions de nœud et de navigateur (probablement seulement des wrappers différents mais je n’ai pas creusé pour confirmer).

La bibliothèque prend également en charge les jolies impressions XML, SQL et CSS, mais je n'ai pas encore essayé ces fonctionnalités.

Un simple pour imprimer les éléments sous forme de chaînes:

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

Ma bibliothèque NeatJSON contient à la fois Ruby et Versions JavaScript . Il est disponible gratuitement dans le cadre d’une licence (permissive) MIT. Vous pouvez voir une démo / convertisseur en ligne sur:
http://phrogz.net/JS/neatjson/neatjson.html

Certaines fonctionnalités (toutes facultatives):

  • Enrouler à une largeur spécifique; si un objet ou un tableau peut tenir sur la ligne, il est conservé sur une ligne.
  • Alignez les deux points pour toutes les clés d'un objet.
  • Triez les clés d'un objet par ordre alphabétique.
  • Mettez en forme les nombres à virgule flottante en un nombre spécifique de décimales.
  • Lors du retour à la ligne, utilisez une version "courte" qui place les crochets d'ouverture / fermeture pour les tableaux et les objets sur la même ligne que la première / dernière valeur.
  • Contrôlez les espaces pour les tableaux et les objets de manière granulaire (entre crochets, avant / après les deux points et les virgules).
  • Fonctionne dans le navigateur Web et en tant que module Node.js.

flexjson inclut une fonction prettyPrint () cela pourrait vous donner ce que vous voulez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top