JavaScript-对象的深浅拷贝

发布于 2019-05-13  114 次阅读


什么是深拷贝什么是浅拷贝?

深拷贝

  • 修改新变量的值不会影响原有变量的值
  • 默认情况下基本数据类型都是深拷贝
let num1 = 123;
        let num2 = num1;
        num2 = 666; // 修改变量的值
        console.log(num1);
        console.log(num2);

浅拷贝

  • 修改新变量的值会影响原有的变量的值
  • 默认情况下引用类型都是浅拷贝
class Person{
            name = "hjs";
            age = 34;
        }
        let p1 = new Person();
        let p2 = p1;
        p2.name = "zs"; // 修改变量的值
        console.log(p1.name);
        console.log(p2.name);

Object.assign()

  • 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
  • 注意点: 只有被拷贝对象中所有属性都是基本数据类型, 以下代码才是深拷贝

浅拷贝是两个对象指向同一个实例对象的地址,所有修改其中一个都会影响到另一个

为了让引用数据类型从默认的浅拷贝转到深拷贝,重新创建一个对象接收被拷贝的对象参数,这样就会在内存中重新开辟一块新的空间,这样修改其中一个对象时就不会影响到另一个对象

  • 可以使用可以使用Object.assign()方法,把被拷贝的对象里的基本数据类型拷贝过去给p2
 class Person{
            name = "hjs";
            age = 34;
        }
let p1 = new Person();
//新建一个对象接收被拷贝的对象参数及属性
let p2 = new Object();
//assign方法可以将第二个参数的对象的属性和方法拷贝到第一个参数的对象中
 Object.assign(p2, p1);
 p2.name = "zs";
 console.log(p1.name);
 console.log(p2.name);
 // 注意点: 只有被拷贝对象中所有属性都是基本数据类型, 以上代码才是深拷贝

以上的方法只适用于操作对象中的基本数据类型,不能完全实现深拷贝

实现真正的深拷贝(基本数据类型及引用数据类型)

  • 自行创建一个depCopy拷贝方法
  • 取出当前遍历到的属性对应的值
  • 判断当前的取值是否是引用数据类型
 class Person{
      name =  "hjs";
      Student = {
        name: "ww",
        age : 3
      };
      score = [1,3,5];

    }

    let depCopy = (target,source)=>{
      for (let key in source) {
        // console.log(key);
        //取出当前遍历到的属性对应的值
        let sourceVulue = source[key];
        //判断当前的取值是否是引用数据类型
        if (sourceVulue instanceof Object){
          //创建一个实例属性赋值给subTarget
          let subTarget = new sourceVulue.constructor;
          // console.log(subTarget);
          //把创建的属性赋值给target
          target[key] = subTarget;
          // console.log(target);
          //使用递归把遍历到的取值(sourceVulue)拷贝到新建的属性里面(subTarget)
          depCopy(subTarget,sourceVulue);
        }else {
          //不是引用类型就直接赋值给target
          target[key] = sourceVulue;
        }
      }
    };
    let p1 = new Person();
    let p2 = new Object();
    //将来通过depCopy传入拷贝及被拷贝对象,把被拷贝所有属性给拷贝对象
    depCopy(p2,p1);

    p2.name = "zs";

    console.log(p1);
    console.log(p2);

    p2.Student.age = 666;
    console.log(p1.Student.age);
    console.log(p2.Student.age);

此时的内存表示图


改变思想才能改变我们的人生