JS 对象深度拷贝方法 js对象赋值问题(对象赋值影响原对象、对象赋值后原对象值随之变化)

11

问题1:

一个对象赋值给另一个对象后,新对象的值更改原对象的参数值随之变化(即改变新对象的值会影响原对象值)

直接用 的方式把一个对象赋值给另一个对象,会导致修改新对象时,原对象也发生变化


原因:

JavaScript 中对象的赋值是默认引用赋值的(两个对象指向相同的内存地址),所以修改另一个对象时,即修改了内存地址里的对象,其他关联对象也会改变  


解决方法(转换类型法): JSON.parse(JSON.stringify(obj))

 注:

普通的对象也可以进行深拷贝,但是!!! 当对象内容项为number,string.boolean的时候,是没有什么问题的。但是,如果对象内容项为undefined,null,Date,RegExp,function,error的时候。使用JSON.stringify()进行拷贝就会出问题了。


解决方法(es6之Object.assign()法):obj2=Object.assign({},obj1)

 注:

Object.assign()方法有不足之处,Object.assign()只是让对象里第一层的数据没有了关联性(即修改obj2.name时obj1.name不会发生变化),但是对象内的对象则跟被复制的对象有着关联性的(即当修改更深层的obj2.name的值时,原对象obj1.name也跟着发生了变化)


终极解决方案:

// 对象深度拷贝方法
function deepCopy(obj) {
    let copy;
    
    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;
    
    // Handle Array
    if (obj instanceof Array) {
        copy = [];
        for (let i = 0, len = obj.length; i < len; i++) {
            copy[i] = deepCopy(obj[i]);
        }
        return copy;
    }
    
    // Handle Object
    if (obj instanceof Object) {
        copy = {};
        for (let attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = deepCopy(obj[attr]);
        }
        return copy;
    }

}

let a = {
xiaoming: {
yuwen: 89,
shuxue: 99,
yingyu: 100 
},
xiaoma: [
'a','b','c'
]
};

let b = a;

let c = Object.assign({}, a);

let d = deepCopy(a);

console.log('@',a,b,c,d);

a.xiaoming.yuwen  = 100;

console.log('#',a,b,c,d);