JavaScript 数据格式/漂亮的打印机

IT技术 javascript debugging json
2021-02-03 14:13:22

我试图找到一种方法以人类可读的形式“漂亮地打印”用于调试的 JavaScript 数据结构。

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

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

6个回答

像这样使用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 文件 - 它可以与任何库等一起使用。

奇怪的是它会导致问题 - 它确实将名称“JSON”引入全局命名空间,因此可能会给您带来问题。添加之前检查“JSON”的命名空间以查看是否存在冲突。
2021-03-24 14:13:22
对此的更新,对于 Firefox 3.5 及更高版本,JSON.stringify 是内置的。( developer.mozilla.org/En/Using_JSON_in_Firefox ),所以如果您只是为了调试目的而尝试查看 JSON 对象,您可以在没有额外 JS 依赖项的情况下进行。
2021-03-25 14:13:22
同样在 Chrome 中。但是, JSON.stringify 在循环数据JSON.stringify((function(){var x = []; x.push(x); return x})())和许多其他类型的对象上失败JSON.stringify(/foo/)
2021-03-27 14:13:22
好吧,原型就是那样邪恶......;)
2021-03-30 14:13:22
这几乎肯定是您将得到的最佳答案。我已经教过 4 到 5 名非程序员阅读和编辑 JSON.stringified 数据结构,并将它们广泛用于配置文件。
2021-03-31 14:13:22

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

在递归调用的行上选择缩进,然后通过在此行之后切换注释行来支持样式。

...我看到你掀起了自己的版本,这很好。游客将有选择。

@RaphaelDDL & PhiLho - 也可以在小对象上触发最大调用堆栈大小;一个具有对自身的属性引用。这样的引用会导致此函数的无限循环。
2021-03-31 14:13:22
这种方法的一个缺点(与 Jason 建议的 JSON.stringify 方法相比)是它没有正确显示对象数组。当您拥有一组对象时,它会显示为 [object Object]。
2021-04-01 14:13:22
我不能用这个。当我尝试转储一些 json 数据时,我得到了无限循环。
2021-04-02 14:13:22
我喜欢 ;) 无法让它正常工作,但如果你不介意,我将无耻地窃取这个概念并编写我自己的 :)
2021-04-11 14:13:22
@Ryan:您的意思是浏览器的本机对象?是的,回顾我的代码,我看到我添加了一条评论: // 如果一个字段是一个对象,那就太糟糕了... :-P 在这里我的测试还可以... 可以转储用户制作的结构。如果您需要更强大的东西,我看到下面有替代方案。
2021-04-12 14:13:22

您可以使用以下

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

在 中Firebug,如果您只是console.debug ("%o", my_object)可以在控制台中单击它并进入交互式对象浏览器。它显示整个对象,并允许您展开嵌套对象。

这也适用于 Chrome(因此大概适用于 Safari)。
2021-03-17 14:13:22
问题是它只显示“最顶层”的对象——我有几十个嵌套对象,我真的需要能够一次看到整个内容,重要的是,看看哪里发生了变化。所以在这种情况下,Firebug 真的不适合我。
2021-03-22 14:13:22
(是的,我知道你可以点击展开它们,但是每次我想转储数据时点击 10 个左右的链接就是我现在正在做的 - 进展非常缓慢)
2021-04-10 14:13:22

对于 Node.js,请使用:

util.inspect(object, [options]);

API 文档