浅拷贝和深拷贝的区别

143 阅读2分钟

数据类型

  • 基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6)
  • 引用类型:Object、Array、Function

基本数据类型保存在栈内存,栈内存分别存储着变量的标识符以及变量的值

引用类型保存在堆内存中,栈内存存储的是变量的标识符以及对象在堆内存中的存储地址,当需要访问引用类型的值时,首先从栈中获取该对象的地址指针,然后再从堆内存中取得所需的数据

基本类型和引用类型的复制方式

  • 基本类型的复制:复制了栈中的值给了新的变量
  • 引用类型的复制:复制了栈中的存储地址(也可以叫堆内存的引用,这个地址指向堆内存的地址),即原来的变量和新变量指向了同一个东西

浅拷贝和深拷贝的区别

深浅拷贝都是针对引用类型。他们都会复制第一层的值,所谓第一层就是key所对应的value值是基本数据类型。到第二层的时候也就是引用类型(子对象),浅拷贝复制的是引用,深拷贝则会递归复制值。

浅拷贝

   function clone(obj){
      let newObj = Array.isArray(obj) ? [] : {};
      for(const key in obj) {
        // hasOwnProperty 可忽略继承过来的(构造函数原型上的)属性
        if (obj.hasOwnProperty(key)) {
          newObj[key] = obj[key]
        }
      } 
     return newObj;
   }
   function Father () {
     this.name = 'F'; 
   }
   Father.prototype.age = 10; 
   const c = new Father(); 
   const cloneC = clone(c);
   console.log('c: ', c);   // c:  Father { name: "F", __proto__: { age: 10 }}
   console.log('cloneC: ', cloneC);  // cloneC:  { name: "F" } ,过滤了原型对象上的age

深拷贝

    function deepClone(obj){
      let newObj = Array.isArray(obj) ? [] : {};
      for(key in obj) {
        // hasOwnProperty 可忽略继承过来的(构造函数原型上的)属性
        if (obj.hasOwnProperty(key)) {
          if (typeof obj[key] === 'object') {
            newObj[key] = deepClone(obj[key])
          } else {
            newObj[key] = obj[key]
          }
        }
      }
      return newObj;
    }

    const o = {
      b: 1,
      c: {
        d: 2,
      }
    }
    const cloneO = deepClone(o)
    cloneO.b = 3;
    cloneO.c.d = 4;
    console.log('o: ', o);   // o: {b: 1, c: {d: 2}}
    console.log('cloneO: ', cloneO);  // // o: {b: 3, c: {d: 4}}