字符串化(转换为JSON)与循环引用一个JavaScript对象字符串化(转换为JSON)与循环引用

2019-05-13 17:57发布

我有其中包含一个循环引用一个JavaScript对象的定义:它引用父对象的属性。

它也有,我不想通过服务器传递功能。 我将如何进行序列化和反序列化这些对象呢?

我读过,要做到这一点的最好方法是使用道格拉斯Crockford的字符串化。 不过,我发现了以下错误在Chrome中:

类型错误:转换圆形结构,以JSON

代码:

function finger(xid, xparent){
    this.id = xid;
    this.xparent;
    //other attributes
}

function arm(xid, xparent){
    this.id = xid;
    this.parent = xparent;
    this.fingers = [];

    //other attributes

    this.moveArm = function() {
        //moveArm function details - not included in this testcase
        alert("moveArm Executed");
    }
}

 function person(xid, xparent, xname){
    this.id = xid;
    this.parent = xparent;
    this.name = xname
    this.arms = []

    this.createArms = function () {
        this.arms[this.arms.length] = new arm(this.id, this);
    }
}

function group(xid, xparent){
    this.id = xid;
    this.parent = xparent;
    this.people = [];
    that = this;

    this.createPerson = function () {
        this.people[this.people.length] = new person(this.people.length, this, "someName");
        //other commands
    }

    this.saveGroup = function () {
        alert(JSON.stringify(that.people));
    }
}

这是我对这个问题,创建了一个测试案例。 有错误的代码内,但本质上我有对象中的对象,并传递给每一个对象的引用,以显示在创建对象时,父对象是什么。 每个对象还包含的功能,这是我不希望字符串化。 我只想属性,如Person.Name

如何发送到服务器之前,序列化和反序列化假设同一JSON传回?

Answer 1:

当你有直接是对象本身的对象的属性发生圆形结构误差( a -> a )或间接( a -> b -> a )。

为了避免错误信息,告诉JSON.stringify当它遇到一个循环引用做什么。 例如,如果您有指向另一人(“母公司”),这可能(也可能不会)指向原来的人一个人,做到以下几点:

JSON.stringify( that.person, function( key, value) {
  if( key == 'parent') { return value.id;}
  else {return value;}
})

到第二参数stringify是一个过滤器的功能 。 这只是转换提到对象的ID,但你可以自由你想打破循环引用你还是要坚持。

您可以测试与以下上面的代码:

function Person( params) {
  this.id = params['id'];
  this.name = params['name']; 
  this.father = null;
  this.fingers = [];
  // etc.
}

var me = new Person({ id: 1, name: 'Luke'});
var him = new Person( { id:2, name: 'Darth Vader'});
me.father = him; 
JSON.stringify(me); // so far so good

him.father = me; // time travel assumed :-)
JSON.stringify(me); // "TypeError: Converting circular structure to JSON"
// But this should do the job:
JSON.stringify(me, function( key, value) {
  if(key == 'father') { 
    return value.id;
  } else {
    return value;
  };
});

顺便说一句,我会选择不同的属性名称为“ parent ”,因为它是在许多语言中的保留字(和DOM)。 这往往造成混乱的道路...



Answer 2:

看来, 道场可以在形式表示JSON循环引用: {"id":"1","me":{"$ref":"1"}}

下面是一个例子:

http://jsfiddle.net/dumeG/

require(["dojox/json/ref"], function(){
    var me = {
        name:"Kris",
        father:{name:"Bill"},
        mother:{name:"Karen"}
    };
    me.father.wife = me.mother;
    var jsonMe = dojox.json.ref.toJson(me); // serialize me
    alert(jsonMe);
});​

生产:

{
   "name":"Kris",
   "father":{
     "name":"Bill",
     "wife":{
          "name":"Karen"
      }
   },
   "mother":{
     "$ref":"#father.wife"
   }
}

注意:您也可以反序列化使用这些循环引用的对象dojox.json.ref.fromJson方法。

其他资源:

如何序列化DOM节点JSON即使有循环引用?

JSON.stringify不能代表循环引用



Answer 3:

我发现了两个合适的模块来处理在JSON循环引用。

  1. CircularJSON https://github.com/WebReflection/circular-json其输出可以被用作输入到.parse()。 它也可以在浏览器和Node.js的另见: http://webreflection.blogspot.com.au/2013/03/solving-cycles-recursions-and-circulars.html
  2. 艾萨克斯JSON-字符串化安全https://github.com/isaacs/json-stringify-safe这可能更具可读性,但不能用于.parse和仅适用于Node.js的

无论这些应该满足您的需求。



Answer 4:

在此线程发生,因为我需要复杂的对象登录到一个页面,因为远程调试在我的特定情况下是不可能的。 发现道格拉斯Crockford的(JSON的拦截器)自己cycle.js,它诠释的循环引用作为字符串,使得它们能够解析后重新连接。 解循环深拷贝是安全的,通过JSON.stringify。 请享用!

https://github.com/douglascrockford/JSON-js

cycle.js:此文件包含两个功能,JSON.decycle和JSON.retrocycle,这使得它能够编码周期性结构和DAGs在JSON,并再恢复它们。 这是一个不被ES5提供的能力。 JSONPath用于表示的链接。



Answer 5:

我用下面的消除循环引用:

JS.dropClasses = function(o) {

    for (var p in o) {
        if (o[p] instanceof jQuery || o[p] instanceof HTMLElement) {
            o[p] = null;
        }    
        else if (typeof o[p] == 'object' )
            JS.dropClasses(o[p]);
    }
};

JSON.stringify(JS.dropClasses(e));


文章来源: Stringify (convert to JSON) a JavaScript object with circular reference