欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 如何判断一个js对象是否存在循环引用

如何判断一个js对象是否存在循环引用

2026/5/28 0:41:08 来源:https://blog.csdn.net/qq_43474235/article/details/139726630  浏览:    关键词:如何判断一个js对象是否存在循环引用

一、背景

在前端JSON.stringfy是我们常用的一个方法,可以将一个对象序列化。 例如将如下对象序列化

const person = { name: 'kalory', age:18}JSON.stringfy(person)
// 结果
'{"name":"kalory","age":18}'将一个数组序列化const arr = [1,2,3,4,5]
// 结果
'[1,2,3,4,5]'const persons = [{ name: 'kalory', age:18},{ name: 'jack', age:48}]
// 结果
'[{"name":"kalory","age":18},{"name":"jack","age":48}]'

我们发现上面对象是可以使用JSON.stringfy序列化的。

  • 但是如果一个对象存在循环引用,序列化会报错,如下 person对象的owner属性指向了自己,存在循环引用
const person = { name: 'kalory', age:18}
person.onwer = person

我们对上面这个对象进行JSON.stringfy,结果如下,会报错:

image.png

我们发现他说不能转化一个“圈结构体为JSON”,是因为这个对象的owner属性指向了自己。在转化的时候会变成死循环。

  • 那么我们如果判断一个对象有没有环呢?

二、实现

2.1 思路

我们判断一个对象有没有循环引用,我们其实并不需要在乎对象的key是什么,只需要判断对象的value。如果value是引用数据类型的时候,有没有指向对象的某一值。

所以我们可以先使用Object.values()拿到对象所有values,然后定义一个cache变量用来存储values中的引用数据类型,然后遍历values

如果cache中存在,那么说明这个对象有环 return true,如果不存在并且是引用数据类型,那么我们就加入cache。当values遍历完都没有reutrn那么说明没有环return false

2.2 递归实现

function existCircular(obj) {let cache = new Set(); function helper(obj) {let values = Object.values(obj);for (let i = 0; i < values.length; i++) {if (cache.has(values[i])) {return true;}// 不是引用数据类型,直接跳过if(typeof values[i] !== 'object' || values[i] === null) continuecache.add(values[i]);let flag = helper(values[i]);// 如果 flag 是 false, 那么继续遍历,如果是 true,说明已经存在环了, 直接 return trueif (flag) {return true;}}return false;}return helper(obj);
}// 测试
const person = { name: 'kalory', age:18}
person.onwer = personexistCircular(person) // true

2.3 BFS实现

const existCircularBFS = (obj) => {let cache = new Set();let values = [obj];while(values.length) {const item =  values.shift()if (cache.has(item)) {return true;}// 基本数据类型跳过if(typeof item !== 'object' || item === null) continuecache.add(item);// 主要这里 Object.values 拿到的是一个数组,我们需要展开push到values// 如果直接 push Object.values(item) 会造成死循话values.push(...Object.values(item))}return false;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词