当前位置: 首页 > Web前端 > JavaScript

我听说你的对象有一个“环”?你是怎么发现的?

时间:2023-03-27 00:27:32 JavaScript

1。手写62+方法学习JavaScript底层原理判断一个对象是否有循环引用已经包含在手写各种源码实现中,也可以直接点击isCyclic快速查看,目前有62+手写实现,欢迎学习一起。2.循环引用不得不说的如下:相信大家之前也遇到过类似的问题,循环引用。如果两个对象互相传递引用或者对象的属性引用自己,就可能造成循环引用。循环引用是旧浏览器中内存泄漏的一个原因,当然,随着改进的垃圾收集算法现在可以很好地处理循环引用,这不再是一个问题。只需3分钟。本文将让你了解哪些情况可能会导致循环引用(重要)?如何判断一个对象是否存在循环引用(重要)?3、循环引用的几种情况常见的循环引用有两种情况,对象相互引用,对象属性引用对象本身3.1对象相互引用letobj1={name:'黑头鱼1'}letobj2={name:'胖头鱼2'}//对象1的属性引用对象2obj1.obj=obj2//对象2的属性引用对象1obj2.obj=obj13.2对象的属性引用对象1本身。直接引用最外层对象letobj={name:'Fatheadfish1'}//对象的属性引用对象本身obj.child=obj2.引用对象的一些属性letobj={name:'Fatheadfish',child:{}}obj.child.obj=obj.child4.如何判断对象是否存在循环引用?根据循环引用可能出现的情况,我们可以尝试写出如下代码4.1源码实现constisCyclic=(obj)=>{//使用Set数据类型存储检测到的对象letstackSet=newSet()letdetected=falseconstdetect=(obj)=>{//如果不是对象类型,可以直接跳过if(obj&&typeofobj!='object'){return}//当要检查的对象已经存在于stackSet中,说明存在循环引用obj){//forobjif(obj.hasOwnProperty(key)){detect(obj[key])}}//对端检测完成后,删除当前对象,防止误判/*例如:对象的属性指向同一个引用,如果不删除,会被认为是循环引用lettempObj={name:'胖头鱼'}letobj4={obj1:tempObj,obj2:tempObj}*/stackSet.delete(obj)}detect(obj)returndetected}4.2测试一//1.对象相互引用letobj1={name:'胖头鱼1'}letobj2={name:'胖头鱼2'}//对象1的属性引用对象2obj1.obj=obj2//对象2的属性引用对象1obj2.obj=obj1console.log(isCyclic(obj1))//trueconsole.log(isCyclic(obj2))//true//2.对象的属性是指对象本身letobj={name:'胖头鱼1'}//对象的属性是指对象本身obj.child=objconsole.log(isCyclic(obj))//true//3.属性的对象引用部分的属性letobj3={name:'FatheadFish',child:{}}obj3.child.obj=obj3.childconsole.log(isCyclic(obj3))//true//4.的属性对象指向同一个引用lettempObj={name:'前端肥头鱼'}letobj4={obj1:tempObj,obj2:tempObj}console.log(isCyclic(obj4))//false//5.其他数据类型console.log(isCyclic(1))//falseconsole.log(isCyclic('胖头鱼'))//falseconsole.log(isCyclic(false))//falseconsole.log(isCyclic(null))//falseconsole.log(isCyclic(undefined))//falseconsole.log(isCyclic([]))//falseconsole.log(isCyclic(Symbol('胖头鱼')))//false5.一个非常小的知识点在最后,感谢阅读如果有兴趣,可以进一步探讨一些有趣的话题:例如:如何在JSON.stringify中输出循环引用的对象。JS的垃圾回收机制如何处理循环引用等等。