具有可变状态的JavaScript日志记录对象

4
这段 JavaScript 代码...
var o = {};
console.dir(o);
o.foo = "bar";
console.dir(o);

...结果会导致相同的交互式树输出显示两次:
Two objects with foo:"bar" shown
这个问题在Stack Overflow上被讨论为一个bug,在Chromium bugWebKit中也有记录(我想其他地方也是如此)。

我理解实现原因,但它使得调试状态对象变得困难(不使用交互式调试器)。在这种情况下,您在日志调用中需要查看对象的不同状态时,您使用什么策略进行日志记录?JSON.stringify()?是否有可以使用的序列化控制台方法?

1个回答

2
我会通过制作一个所需记录内容的“深拷贝”,并将该副本传递给console.dir()来解决此问题。类似这样的代码可以很好地解决问题:
function deep_copy(ref)
{
    var r;
    var i;

    if(isHash(ref))
    {
        r = {};
        for(i in ref)
                r[i] = deep_copy(ref[i]);
    }
    else if(isArray(ref))
    {
        r = [];
        for(i = 0; i < ref.length; i++)
            r[i] = deep_copy(ref[i]);
    }
    else
    {
        r = ref;
    }

    return r;
}

如果你不想麻烦处理这样的问题,那么使用 JSON.stringify 是一个很好的解决方法,并且如果它在浏览器中是本地的,它不会变得更慢。

console.dir(JSON.parse(JSON.stringify(o));

虽然你的想法很好,但是你缺少一些代码(例如 isHashisArray 的定义),而且这种方法无法处理已经存在的对象属性(例如函数或正则表达式)或数组上的自定义属性。不过,我没有考虑使用 stringify/parse 来复制一个对象并保留树形结构。这个想法不错。 - Phrogz
2
使用 stringify 的一个问题是它无法处理循环引用。 - Phrogz
真的,@Phrogz,尽管JSON.stringify()会崩溃,但我上面的代码至少会无限循环!(哦不!)=) - Yobert
关于 stringify 的循环引用问题。有些库声称可以解决该问题,例如 circular-json、json-stringify-safe 等。 - Josef.B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接