美文网首页
js对象的循环引用

js对象的循环引用

作者: skoll | 来源:发表于2022-06-24 23:13 被阅读0次

问题简述

1 .当一个对象的属性是自己的时候,使用JSON.stringify或者一般的没有处理的deepClone的时候会发现栈溢出

//如下代码
var b = {
}
var a = {
    b: b
}
b.a = a
console.log(a)
image.png

常见情况

1 .json序列化的时候,序列化的对象尽量避免循环依赖,子类不定义与父类相同名称的成员,避免定义非成员变量的getter、setter方法

确认问题

1 .出现循环引用的时候算是bug么?要怎么处理
2 .webpack里面也会有这种情况,循环依赖a-b-c-a

1 .根据module ID,到installedMoodules里面去找之前有没有加载过,如果有加载过,就直接返回上次的
2 .如果没有,就新建一个,并且赋值给installedModules[moduled]

3 .对象存在循环引用的时候,打印不会出现栈溢出,深拷贝的时候,才会的导致栈溢出

如何判断一个对象出现了循环引用

1 .定义了引用类型的变量后该变量存的是堆内存的地址,通过地址访问堆内存的数据,从而产生了引用。而基本数据类型定义后存储的是数据值,不需要引用
2 .在js中对两个引用类型使用 === 判断是对两者的地址进行判断
3 .所以判断是否存在循环引用,可以简单定义为对象内部的属性是否和对象本身的地址相同

var obj = {
            a: 1,
        }
        obj.c = obj
        obj.b = obj

        const keyMap = new Map();
        // keyMap.set(obj, "1");
        // keyMap.set(b, "2");
        function circle(target) {
            const keys = Object.keys(target);
            for (let i = 0; i < keys.length; i++) {
                const key = keys[i];
                const val = target[key];
                if (keyMap.has(val)) {
                    return true
                } else {
                    keyMap.set(val, key)
                    if (typeof val === 'object') {
                        circle(val)
                    }
                }
            }
            return false;
        }
        console.log(circle(obj))

//方法2 
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;
}

处理方法

1 .去除对象中涉及到的循环引用的属性.消除循环引用JSON.decycle方法可以解除循环

{"a":{"b":{"$ref":"$"}}}

2 .将循环引用中的一个对象缓存起来,以避免重复序列化或者创建

1 .WeakMap来记录对象是否被克隆,主要考虑一下三点。
2 .WeakMap对象是key=>value形式,不会重复记录
3 .WeakMap是弱引用,如果不在使用,空间会直接释放

相关文章

  • js对象的循环引用

    问题简述 1 .当一个对象的属性是自己的时候,使用JSON.stringify或者一般的没有处理的deepClon...

  • iOS底层 -- Blcok本质之循环引用

    一、产生循环引用的原因 由图可知,person对象强引用block,block强引用person对象,形成循环引用...

  • iOS 内存泄漏之循环引用

    何为循环引用?简单理解:对象A强引用B,对象B也强引用A; 何时会发生循环引用?使用delegate、block的...

  • iOS开发循环引用

    一、循环引用的产生 1.说明 -- :表示弱引用。 -> :表示强引用。 循环引用可以简单理解为对象A引用了对象B...

  • iOS 内存管理面试题(循环引用)

    循环引用 循环引用的实质:多个对象相互之间有强引用,不能释放让系统回收。 如何解决循环引用? 1、避免产生循环引用...

  • iOS 循环引用

    1. 循环应用的分类: 自循环引用; 相互循环引用; 多循环引用; 自循环引用: 一个对象中有一个成员变量A; 如...

  • iOS基础 Block解决循环引用

    block 循环引用循环引用 A对象持有B,B又持有A,互相强引用 解决循环引用问题:ARC 和MRC ARC:...

  • 内存管理-循环引用

    三种类型循环引用 自循环引用 相互循环引用 多循环引用 自循环引用 假如有一个对象,内部强持有它的成员变量obj,...

  • JSON.stringify cycle对象

    对于有循环引用的JS对象,用JSON.stringify会产生typeError。 解决办法:编写一个replac...

  • iOC中block下的__block、__Strong、__w

    循环引用机理 两个对象相互持有,这样就会造成循环引用,如下图所示 图中,对象A持有对象B,对象B持有对象A,相互持...

网友评论

      本文标题:js对象的循环引用

      本文链接:https://www.haomeiwen.com/subject/asxvvrtx.html