js -深浅拷贝

区别:

(1)深拷贝(深度克隆)
特点:拷贝的时候会生成一份新的数据,修改拷贝以后的数据不会原数据。
(2)浅拷贝(对象,数组)
特点:拷贝的时候只是拷贝了一份引用,修改拷贝以后的数据会影响原来的数据。

 

浅拷贝:

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

 

 

方式一:

直接等号赋值

 let obj1 = {
     name:'小王',
     obj:{
         age:20
     }
 }
 let obj1Copy = obj1
 obj1Copy.name = '小李';
 obj1Copy.obj.age = 22;
 console.log(obj1)               //{ name: '小李', obj: { age: 22 } }
 console.log(obj1Copy === obj1)  //true

  

方式二:

使用Object.assign()  如果对象的value全是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象

 let obj1 = {
    name:'小王',
     obj:{
         age:20
     }
 }
 let obj1Copy ={}
 Object.assign(obj1Copy,obj1);
 obj1Copy.name = '小李';
 obj1Copy.obj.age = 22;
 console.log(obj1)                //{ name: '小王', obj: { age: 22 } }  原数据的obj.age变了,浅拷贝
 console.log(obj1Copy === obj1)   //false

  

方式三:

for···in循环(只循环第一层)

 let obj1 = {
     name:'小王',
     obj:{
         age:20
     }
 }
 function simpleCopy(obj1) {
     let obj2 = Array.isArray(obj1) ? [] : {};
     for (let i in obj1) {
     obj2[i] = obj1[i];
    }
     return obj2;
  }
  let obj1Copy = simpleCopy(obj1)
  obj1Copy.name = '小李';
  obj1Copy.obj.age = 22;
  console.log(obj1)               //{ name: '小王', obj: { age: 22 } }
  console.log(obj1Copy === obj1)  //false

  

深拷贝:

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

 

 

 

 

 

 

方式一:

通过JSON对象来实现深拷贝

缺点:
- 会忽略`undefined`
- 会忽略`symbol`
- 会忽略函数
- 不能解决循环引用的对象

 let obj1 = {
     sex:undefined,
     name:'小王',
     obj:{
         age:20
     },
     fn:()=>{}
 }

 let obj1Copy = JSON.parse(JSON.stringify(obj1))
  obj1Copy.name = '小李';
  obj1Copy.obj.age = 22;
 console.log(obj1)        //{ sex:undefined,name: '小王', obj: { age: 20 },fn:()=>{} }
 console.log(obj1Copy)   //{ name: '小李', obj: { age: 22 } }

  

方式二:

递归拷贝所有层级属性

hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中(非继承属性)是否具有指定的属性,如果 object 具有带指定名称的属性,则 hasOwnProperty 方法返回 true,否则返回 false。此方法不会检查对象原型链中的属性;该属性必须是对象本身的一个成员。

let obj1 = {
    sex:undefined,
    name:'小王',
    obj:{
        age:20
    },
    fn:()=>{}
}

let deepClone = function (obj1) {
   let obj2 = Array.isArray(obj1)?[]:{}
   if(obj1 && typeof obj1 === 'object'){
    for(key in obj1){
        if(obj1.hasOwnProperty(key)){
            //判断ojb子元素是否为对象,如果是,递归复制
           if(obj1[key] && typeof obj1[key] ==='object'){
               obj2[key] = deepClone(obj1[key])
           }else{
               //如果不是,简单复制
               obj2[key] = obj1[key]
           }
        }
    }
   }
   return obj2
}
let obj1Copy = deepClone(obj1);
obj1Copy.sex = '男';
obj1Copy.obj.age = 22;
console.log(obj1)      //{sex: undefined, name: "小王", obj: {age:20}, fn: ƒ}
console.log(obj1Copy)  //{sex: 男, name: "小王", obj: {age:22}, fn: ƒ}

  

 

posted @ 2020-10-16 14:03  北巷听雨  阅读(101)  评论(0编辑  收藏  举报
返回顶端