且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-01-17 16:26:58

循环结构 当您拥有对象的属性即对象本身直接(a ->a) 或间接 (a -> b -> a).

Circular structure error occurs when you have a property of the object which is the object itself directly (a -> a) or indirectly (a -> b -> a).

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

To avoid the error message, tell JSON.stringify what to do when it encounters a circular reference. For example, if you have a person pointing to another person ("parent"), which may (or may not) point to the original person, do the following:

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

stringify 的第二个参数是一个过滤函数.在这里,它只是将引用的对象转换为其 ID,但您可以随意破坏循环引用.

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.

您可以使用以下代码测试上述代码:

You can test the above code with the following:

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)中的保留字.这往往会导致混乱...

BTW, I'd choose a different attribute name to "parent" since it is a reserved word in many languages (and in DOM). This tends to cause confusion down the road...