I've got a JavaScript object definition which contains a circular reference: it has a property that references the parent object.

它还有一些我不想传递给服务器的功能.如何序列化和反序列化这些对象?

I've read that the best method to do this is to use Douglas Crockford's stringify. However, I'm getting the following error in Chrome:

TypeError: Converting circular structure to 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));
    }
}

This is a test case that I created for this question. There are errors within this code but essentially I have objects within objects, and a reference passed to each object to show what the parent object is when the object is created. Each object also contains functions, which I don't want stringified. I just want the properties such as the Person.Name.

假设返回的是相同的JSON,那么在发送到服务器之前如何序列化并反序列化它?

推荐答案

Circular structure当你拥有一个直接(a -> a)或间接(a -> b -> a)的对象属性时,就会发生错误.

为了避免该错误消息,告诉JSON.stringify在遇到循环引用时该怎么做. 例如,如果您有一个人指向另一个人("父级"),该人可能指向(也可能不指向)原始人,请执行以下操作:

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

The second parameter to stringify is a filter function. Here it simply converts the referred object to its ID, but you are free to do whatever you like to break the circular reference.

您可以使用以下内容测试上面的代码:

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

顺便说一句,我会 Select 一个不同的属性名"parent",因为它在许多语言(和DOM)中都是保留字.这往往会造成混乱的道路上...

Jquery相关问答推荐

使用jquery ui来回滑动切换

如何根据另一个 radio Select 并切换?

在 JQuery DataTable 中通过按钮单击传递 ID

从 React 到 Node 服务器的 ajax 调用中的数据未定义

DataTables - this.api 用于回调函数中的多个表

Jquery $(this) 子 Select 器

JSLint 错误:将调用移动到包含函数的括号中

元素上的 jQuery Change 事件 - 有什么方法可以保留以前的值?

在 JavaScript 中解析 URL

动态设置 iframe src

在 800px 后在 scrollDown 上显示 div

iframe 仅显示页面的特定部分

专业的基于 jQuery 的 Combobox 控件?

输入元素上的 Javascript 更改事件仅在失go 焦点时触发

无法更新数据属性值

设置 JQuery event.preventDefault() 时绕过 window.open 上的弹出窗口阻止程序

JavaScript 等效于 jQuery 的扩展方法

jQuery select2 获取 Select 标签的值?

只绑定一次事件

jquery ui Dialog:无法在初始化之前调用对话框上的方法