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

我试图find一种方法来pretty print JavaScript数据结构以可读的forms进行debugging。

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

所有这些东西,我可以处理自己,除了find一个很好的方法来将JavaScript数据结构转储为可读的string。 JSON会做,但它确实需要很好地格式化和缩进。 我通常使用Firebug的优秀的DOM倾销的东西,但我真的需要能够看到整个结构,这似乎不可能在Firebug。

任何build议,欢迎。

提前致谢。

我写了一个函数来转储一个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值(项目数)为另一个目的。 使函数仅返回string是微不足道的。
注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$/, ""); } 

在recursion调用的行上select你的缩进,通过在这个之后切换注释行来支持样式。

…我看到你掀起了自己的版本,这是很好的。 游客将有一个select。

像这样使用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... 

variablestext将如下所示:

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

顺便说一句,这只需要那个JS文件 – 它将适用于任何库等。

Firebug ,如果你只是console.debug ("%o", my_object)你可以在控制台上点击它并input一个交互式对象浏览器。 它显示整个对象,并让您展开嵌套的对象。

您可以使用以下内容

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

对于那些寻找一个真棒的方式来看你的对象, 检查prettyPrint.js

创build一个带有可configuration视图选项的表格,将其打印在文档的某处。 比在console更好看。

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

在这里输入图像描述

我在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发布在这里,以便将来可能会有所改变。

对于Node.js,使用:

 util.inspect(object, [options]); 

API文档

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使用的unit testing框架)使用略微修补的jsDump版本。


JSON.stringify()在某些情况下不是最好的select。

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

以PhiLho的领导(非常感谢:)),我最终写了我自己的,因为我不能让他做我想做的事情。 这是相当粗糙和准备,但它做我需要的工作。 谢谢大家的优秀build议。

我知道,这不是一个好的代码,而是它的价值所在。 有人可能会觉得它有用:

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

我认为J. Buntings使用JSON.stringify的回应也很好。 另外,如果你正在使用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; } 

许多人在这个线程中编写代码,对各种陷阱有很多评论。 我喜欢这个解决scheme,因为它看起来很完整,并且是一个没有依赖关系的文件。

浏览器

的NodeJS

它“开箱即用”,并有节点和浏览器版本(大概只是不同的包装,但我没有挖掘确认)。

该库还支持漂亮的打印XML,SQL和CSS,但我没有尝试过这些function。

一个简单的打印作为string的元素:

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

我的NeatJSON库有Ruby和JavaScript版本 。 它根据(许可)MIT许可证免费提供。 您可以在以下url查看在线演示/转换器:
http://phrogz.net/JS/neatjson/neatjson.html

一些function(全部可选):

  • 裹到一个特定的宽度; 如果一个对象或数组可以放在线上,它将保持在一行上。
  • alignment对象中所有键的冒号。
  • 按字母顺序将键sorting。
  • 将浮点数格式化为特定的小数位数。
  • 在包装时,使用一个'short'版本,将数组和对象的开放/closures括号放在第一个/最后一个值的同一行上。
  • 以细粒度的方式控制数组和对象的空白(在括号内,在冒号和逗号之前/之后)。
  • 在Web浏览器中工作,并作为Node.js模块工作。

flexjson包含一个prettyPrint()函数,可能会给你你想要的。