对象的浅拷贝与深拷贝理解与多种方式实现——JavaScript

送分小仙女□ 提交于 2019-12-08 04:48:51

对象的浅拷贝:

概念: 浅拷贝就是指拷贝引用,新生成的引用和原来的引用都是指向同一个对象的实例,彼此之间的操作会相互影响。

对象的深拷贝:

概念: 在堆中重新开辟内存,把原引用对应的对象实例中所有的内容进行拷贝,因此保证了深拷贝的对象和原来的对象是完全隔离的,他们之间相互没有影响。

对象的浅拷贝实现:

  1. 直接赋值:
let obj = {
  name:"张三",
}

let objOne = obj;

console.log(objOne===obj);  //true
  1. 遍历将要复制的对象,对新对象添加其属性(又叫不完全深拷贝或一层拷贝):
let obj = {
  name:"张三",
  age:"18",
  adr:"北京",
  like:{
    first:"pingpang",
    second:"eat",
    third:"sleep"
  }
}
let objOne = {};
for(let i in obj){
   if(obj.hasOwnProperty(i)){  //为了不复制原型链里继承的属性
     objOne[i]=obj[i];
   }
}
console.log(objOne);   //与obj一致
console.log(objOne===obj);   //false
console.log(objOne.like===obj.like);   //true

第二种方式就是进行了一层深拷贝,即在堆内存中重新开辟了一块地址,让objOne指向它。但是此对象里面的属性是完全复制obj里的,即浅拷贝。所以objOne里的like(引用类型)与obj里的like指的是同一个东西。这种不完全深拷贝也叫浅拷贝。

  1. object.assign
    可实现如第二方式的一层深拷贝。

对象的深拷贝实现:

  1. 利用JSON方法实现:
let obj = {
  name:"张三",
  age:"18",
  adr:"北京",
  like:{
    first:"pingpang",
    second:"eat",
    third:"sleep"
  }
}
let objOne = JSON.parse(JSON.stringify(obj));

console.log(objOne);   //与obj一致
console.log(objOne===obj);  //false
console.log(objOne.like===obj.like); //false

用JSON方法拷贝对象的缺点是,如果对象中含有属性的值是null ,undefined ,function类型时将不会被拷贝。

  1. 利用递归思想完成深拷贝:
       function cloneObjFunction(obj){   //构造函数,复制传入的对象
            for(let i in obj){
                if(obj.hasOwnProperty(i))     //为了不复制原型链里继承的属性
                this[i]=att(obj[i]);     //传入属性,根据属性值的类型返回相应数据
            }
        }
        function att(attr){    //属性判断函数,如果是对象就返回一个与它一样的新对象。     
             if(typeof attr === "object"&&attr!=null){
                return new cloneObjFunction(attr);
             }else{
                return attr;
             }
        }

       let obj = {
            name: {
                aaa: {
                    bbb: {
                        ccc: {
                            ddd: {
                                name: "jack",
                            },
                            DDD: "444"
                        },
                        CCC: "333",
                    },
                    BBB: "222",
                },
                AAA: "111",
            },
            age:"18",
        }
         
       let obj1 = new cloneObjFunction(obj);//拷贝成功.
       console.log(obj1.name.aaa.bbb.ccc===obj.name.aaa.bbb.ccc)  //false
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!