JavaScript数据格式/漂亮打印机

时间:2020-03-06 14:41:36  来源:igfitidea点击:

我正在尝试找到一种以人类可读形式"漂亮打印" JavaScript数据结构进行调试的方法。

我有一个相当大和复杂的数据结构存储在JS中,我需要编写一些代码来对其进行操作。为了弄清楚我在做什么和哪里出了问题,我真正需要的是能够完整地查看数据结构,并在每次通过UI进行更改时对其进行更新。

除了找到一种将JavaScript数据结构转储到人类可读的字符串的好方法之外,我还能处理所有这些事情。 JSON可以,但是确实需要很好地格式化和缩进。通常,我通常使用Firebug出色的DOM转储工具,但是我确实需要能够立即查看整个结构,这在Firebug中似乎是不可能的。

欢迎任何建议。

提前致谢。

解决方案

在" Firebug"中,如果我们只是" console.debug"("%o",my_object),则可以在控制台中单击它并输入一个交互式对象资源管理器。它显示了整个对象,并允许我们扩展嵌套的对象。

flexjson包含一个prettyPrint()函数,可能会为我们提供所需的内容。

像这样使用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文件即可。

我写了一个函数来以可读的形式转储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$/, "");
}

选择带有递归调用的行上的缩进,然后在此行之后切换注释行,以支撑样式。

...我看到我们整理了自己的版本,很好。参观者将有选择。

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

这实际上只是对Jason Bunting的"使用Crockford的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;

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