深拷贝,浅拷贝

205 阅读3分钟

深浅拷贝概念

image.png

浅拷贝

创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个 地址,就会影响到另一个对象。

深拷贝

会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即 发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。”

1、浅拷贝

                name: 'ajax',
                age: 18,
                family: {
                    baby: '来自m78星云那美克星及北爱尔兰洛克王国皇家骑士学院的靓仔'
                }
            }
            
            // 对象直接赋值后会相互影响
            // const o = obj
            // o.name = 'red'
            // console.log(o.name, obj.name);//'red'  'red'

如果属性是基本类型,拷贝的就是基本类型的值,因此对象直接赋值后会相互影响

    // 浅拷贝  一层对象o和obj不会互相影响  多层对象会影响
    // const o = {...obj}
    // o.age = 20
    // console.log(o.age, obj.age); //20  18
    // Object.assign(o, obj) 和 o = {...obj}  效果一样
    
    
    const o = {}
    Object.assign(o, obj)
    o.age = 30
    console.log(o.age, obj.age); //30  18

如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象

image.png

那么如何做到拷贝一个对象,并且拷贝的对象发送变化时不会影响源对象的数据呢? 那就要介绍一下深拷贝了

2、深拷贝

I、利用递归函数实现深拷贝

我们需要遍历旧对象,并判定对象元素类型 》如果对象为数组,再次循环赋值 》》判定对象为对象类型时再次循环赋值 》》》如果对象为简单数据类型,直接进行赋值

  • 万物皆对象
        const o = {}
        function deepCopy(newobj, oldobj) {
            for (let k in oldobj) {
                if (oldobj[k] instanceof Array) {
                    // 当对象元素为数组时 再次循环赋值
                    // newobj[k]接受[]
                    newobj[k] = []
                        // oldobj[k] ['乒乓球', '足球']
                    deepCopy(newobj[k], oldobj[k])
                } else if (oldobj[k] instanceof Object) {
                    // 因为数组也属于对象   所以要在对象前面判断
                    // 当对象元素为对象时 再次循环赋值
                    // newobj[k]接受{}
                    newobj[k] = {}
                        // oldobj[k] ['乒乓球', '足球']
                    deepCopy(newobj[k], oldobj[k])
                } else {
                    // 对象元素不为数组则直接赋值
                    // newobj[k] 新对象的属性名 = 旧对象属性值
                    // k 属性名  oldobj[k]属性值
                    newobj[k] = oldobj[k]
                }
            }
        }
        deepCopy(o, obj)
        o.age = 20
        o.hobby[0] = '篮球'
        console.log(o); //{uname: 'pink', age: 20, hobby:['篮球', '足球']}
        console.log(obj); ////{uname: 'pink', age: 18, hobby:['乒乓球', '足球']}

II、利用lodash实现深拷贝 引入js文件

我们也可以利用lodash插件来完成深拷贝

        // const o = _.cloneDeep(obj)
        const obj = {
            uname: 'pink',
            age: 18,
            hobby: ['乒乓球', '足球']
        }

image.png 网址传送门```````````www.lodashjs.com

III、JSON实现深拷贝

            uname: 'pink',
            age: 18,
            hobby: ['乒乓球', '足球'],
            family: {
                baby: '来自m78星云那美克星及北爱尔兰洛克王国皇家骑士学院的靓仔'
            }
        }

        // 利用JSON实现深拷贝   先转换为JSON字符串  再转换为对象  则使新对象内容和旧对象一样  地址不一样
        const o = JSON.parse(JSON.stringify(obj))
        o.family.baby = '123'
        console.log(o, obj);

后记

若发现内有语句或逻辑混乱的地方,还请各路大神指正。 image.png