有没有办法在JavaScript中测试循环引用? [英] Is there a way to test circular reference in JavaScript?

查看:140
本文介绍了有没有办法在JavaScript中测试循环引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作游戏,而且我遇到了一个问题...当我尝试保存时,JSON失败并报告正在某处制作循环引用。我不认为它实际上是,我看不到它,所以是否有算法或任何可以告诉我它究竟在哪里(在哪些对象和东西之间)?另外,是否有可以保存循环引用的JSON替代方案?我正在运行一个node.js服务器,我看到这个,但我无法得到它工作(它不是作为我可以在我的代码中需要()的模块。)

I'm making a game, and I've come across a problem... When I try to save, JSON fails and reports that circular reference is being made somewhere. I don't think it actually is, I can't see it, so is there an algorithm or anything which could tell me where it is exactly (between which objects and stuff)? Also, is there a JSON alternative that can save circular reference? I'm running a node.js server, I saw this, but I can't get it to work (it's not made as a module i can require() in my code).

推荐答案

如果你想序列化一个循环引用,所以你可以保存它,你需要使引用虚拟,因为它不能被序列化为循环引用,因为这将导致序列化永远序列化相同的对象圈(或至少直到运行时已经内存不足了。

If you want to serialize a circular reference so you can save it, you need to make the reference "virtual" in that it can't be serialized as a circular reference, since that would cause serialization to serialize the same circle of objects forever (or at least until the runtime has run out of memory).

因此,您只需存储指向对象的指针,而不是存储循环引用本身。指针将类似于 ref:'#path.to.object',可以在反序列化时解析,以便将引用指向实际对象。你只需要打破序列化的引用就可以序列化它。

So instead of storing the circular reference itself, you just store a pointer to the object. The pointer will just be something like ref : '#path.to.object' that can be resolved when you deserialize so you point the reference back to the actual object. You just need to break the reference on serialization to be able to serialize it.

在JavaScript中发现循环引用可以通过递归遍历所有对象来完成(使用 for(x in y)),在数组中存储 x 并比较每个 x 使用身份运营商(又名严格比较运营商对于临时数组中的每个 z ,=== 。每当 x === z 等于true时,使用将被序列化为上述的占位符替换对 x 的引用提到 ref

Discovering a circular reference in JavaScript can be done by recursively iterating through all objects (with for (x in y)), store x in an array and compare each x with the identity operator (a.k.a. strict comparison operator) === for each z in the temporary array. Whenever x === z equals true, replace the reference to x with a placeholder that will be serialized to the above mentioned ref.

将数组保留在已访问对象上的替代方法是污染对象通过在它们上设置属性来迭代,就像在这个非常天真的例子中一样:

An alternative to keeping an array over "visited" objects is to "taint" the objects you iterate through by setting a property on them, like in this very naïve example:

for (x in y) {
    if (x.visited) {
       continue;
    }

    x.visited = true;
}

这篇关于有没有办法在JavaScript中测试循环引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆