对象的深浅拷贝

时间:2022-04-04 19:48:49

说到拷贝对象,大家可能会先想到Object.assign这个方法,但是它并不是那么完美,它只会拷贝一层对象,如果对象里面还有对象它就引用了原来的对象。具体看下面代码


01

一层拷贝没任何问题

let obj = {
   aa: 11

}

let newObj = Object.assign({}, obj);

obj.aa = 22;

console.log(newObj.aa); //11

console.log(obj.aa); //22



02

多层拷贝就变成引用了

let obj = {
   aa: 11,
   bb: {
       cc: 22
   }
}

let newObj = Object.assign({}, obj);

obj.bb.cc = 33;

console.log(newObj.bb.cc); //33

console.log(obj.bb.cc); //33


像上面这样拷贝对象我们叫浅拷贝,其实我们也可以通过for-in循环来模拟浅拷贝


let obj = {
   aa: 11,
   bb: {
       cc: 22
   }
}

let newObj = {};

for (const key in obj) {
   newObj[key] = obj[key];
}



03

下面实现一个对象的深拷贝

function copyObj(options) {

    return copy(options)
}

function copyAry(ary) {

    let newAry = []

    for (const item of ary) {

        let value = item;

        if (Object.prototype.toString.call(value) === "[object Object]") value = copyObj(value);

        if (Object.prototype.toString.call(value) === "[object Array]") value = copyAry(value);

        newAry.push(value);
   }

    return newAry;
}

function copy(obj) {

    let newObj = {};

    for (const key in obj) {

        let value = obj[key];

        if (Object.prototype.toString.call(value) === "[object Object]") value = copyObj(value);

        if (Object.prototype.toString.call(value) === "[object Array]") value = copyAry(value);
       newObj[key] = value;
   }

    return newObj;
}


//测试一下上面的代码

let obj = {aa: 11, bb: {cc: [0, [1]]}}

let newObj = copyObj(obj);

obj.bb.cc[1][0] = 666;

console.log(newObj.bb.cc[1][0]) //1

console.log(obj.bb.cc[1][0]) //666


对象的深浅拷贝

点击“阅读原文”查看源码