我我的的理解是,若是一个对象的值等于父级(祖父级,曾祖父级....),则说明是循环引用了。来看下面一个例子:ajax
用上面代码来解释我定义的循环引用:a.info
的值是a
,而a
刚好是a.info
的父级,因此这里就是循环引用了。数组
首先,循环引用对象原本没有什么问题,序列化的时候才会发生问题,好比调用JSON.stringify()
对该类对象进行序列化,就会报错: Converting circular structure to JSON.
,而序列化需求很常见,好比发起一个ajax请求提交一个对象就须要对对象进行序列化。bash
针对上面这样的问题,能够经过JSON
扩展包的var c = JSON.decycle(a)
和var a = JSON.retrocycle(c)
来处理。这里就不作过多的解释了。函数
手动写一个方法来判断对象是否存在循环引用,来看下边一段代码:测试
function cycle(obj, parent) {
//表示调用的父级数组
var parentArr = parent || [obj];
for (var i in obj) {
if (typeof obj[i] === "object") {
//判断是否有循环引用
parentArr.forEach((pObj) => {
if (pObj === obj[i]) {
obj[i] = "[cycle]"
}
});
cycle(obj[i], [...parentArr, obj[i]])
}
}
return obj;
}
复制代码
上面函数中,parentArr
为取值的全部父级的一个集合;ui
循环对象,若是对象是一个object
类型的,先循环数组parentArr
,判断该值是不是parentArr
中的引用,若是是,则存在循环引用,并把循环引用值设置成特殊标识"[cycle]"
,接着再进行递归调用,而且把对应取值链上的父级集合传递下去。spa
测试:code
var a = {
b:{
c:{}
}
};
a.b.c.d = a;
console.log(cycle(a));
复制代码
结果以下: cdn
a.b.c.d
本来是一个循环引用的
a
值,通过处理之后,变成了循环引用的标识;
内容就这么多,有错误但愿大佬能够多多指点,交流才能进步!对象