JavaScript数据格式化/漂亮的打印机
-
02-07-2019 - |
题
我试图找到一种方法 pretty print
JavaScript数据结构中的一个人可读形式为调试。
我有一个相当大而复杂的数据结构被存储在JS和我需要编写一些代码操纵。为了工作我在做什么和我要去哪里错了,我真正需要的是能够看到的数据结构的全部内容,并更新它每当我做出改变,通过用户界面。
所有的这些东西我能处理我自己,除了发现一个好的方式转储JavaScript数据结构的一个人可读串。JSON会做,但它确实需要很好的格式化和缩进。我通常使用萤火虫的优DOM倾销的东西对于这一点,但我真的需要能够看到整个结构的一次,这似乎不可能在萤火虫.
任何建议都是受欢迎的。
在此先感谢。
解决方案
我编写了一个以可读形式转储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$/, "");
}
使用递归调用在行上选择缩进,并通过在此之后切换注释行来支撑样式。
......我看到你掀起了自己的版本,这很好。游客可以选择。
其他提示
使用 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文件 - 它可以与任何库等一起使用。
您可以使用以下
<pre id="dump"></pre>
<script>
var dump = JSON.stringify(sampleJsonObject, null, 4);
$('#dump').html(dump)
</script>
在 Firebug
中,如果您只是 console.debug(&quot;%o&quot;,my_object)
,您可以在控制台中单击它并输入交互式对象资源管理器。它显示整个对象,并允许您展开嵌套对象。
对于那些寻找查看对象的绝佳方式的人,请检查prettyPrint.js
创建一个包含可配置视图选项的表,以便在doc上的某个位置打印。比 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 here ,以便将来可能需要进行任何更改。
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
以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;
我认为J. Buntings对使用JSON.stringify的反应也很好。另外,如果碰巧使用YUI,可以通过YUIs JSON对象使用JSON.stringify。在我的情况下,我需要转储到HTML,因此更容易调整/剪切/粘贴PhiLho响应。
function dumpObject(obj, indent)
{
var CR = "<br />", SPC = " ", 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;
}
将元素打印为字符串的简单方法:
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 图书馆拥有红宝石和 JavaScript版本.它是免费提供下一个(许可)麻省理工学院许可证。你可以查看的网上模拟转换器:
http://phrogz.net/JS/neatjson/neatjson.html
一些特征(所有optional):
- 包装到特定的宽度;如果一个物体或阵列可以适应在线,这是保持在一线。
- 齐的分号的所有钥匙在一个对象。
- 排序的关键对象的字母顺序排列。
- 格式浮点数到特定数量的小数。
- 当包装,使用一个"短"的版本,使开/闭括号内,供阵列和物体在同一行为的第一个最值。
- 控制空白,为数组和对象在一颗粒状的方式(括号内,以前/后的冒号和逗号).
- 在工作的网络浏览器和作为一个Node.js 模块。
flexjson 包含一个prettyPrint()函数这可能会给你你想要的东西。