浅拷贝和深拷贝

162 阅读2分钟

浅拷贝只是拷贝一层(基础数据类型),更深层次对象级别的拷贝引用(复合数据类型) 第一种: 浅拷贝

  需求:把 obj拷贝给 o 
  
  let obj ={id:1, name:"and"  , msg{ age: 18} };
  
  let o ={}; 
  方法一:  
 利用遍历实现浅拷贝
  for(let k in obj) {
    注: k代表属性名  obj[k]代表属性值
    
    o[k] = obj[k]; 
  }
  
  o.msg.age = 20 ;    //修改其中一个
  
  打印  obj.msg.age  和  o.msg.age ?
  
  结果都是20说明:(复合数据类型)只是拷贝(地址存在栈里)给新对象 o ,指向同一个堆数据,彼此修改有影响。
  

  方法二:推荐使用 ES6新增方法可以浅拷贝
   语法:Object.assign(给谁浅拷贝,被拷贝的)
   
   Object.assign(o,obj)
   
     打印  obj.msg.age  和  o.msg.age ?
    结果同上一致

浅拷贝(复合数据类型)如图:

Snipaste_2021-06-28_02-55-17.png

深拷贝拷贝多层,每一级别的数据都会拷贝

通俗:深拷贝(复合数据类型),在堆开辟自己内存空间复制(复合数据类型),彼此修改不影响彼此



   需求:把 obj拷贝给 o 
   
    let obj ={id:1, name:"and"  , msg{ age: 18} ,arr : ['red','pink']};
    
     let o ={}
     
    方法一:利用递归函数,拷贝多层(复合类型数据)
    
   funtion deepCopy (new , old){
      for(let k in old ) {
        k代表属性名  old[k]代表属性值 
       
        let item =old[k];  注:存储属性值用于判断类型
        
        1.判断数据属于那种类型
        
        if(item instanceof Array){
        2. 判断这个值是否是数组(复合数据类型)
         new[k] = [] ;           注:是数组类型,值先定义空数组,方便数据
         deepCopy ( new[k] , item)      注:把旧值(这里代表obj)深拷贝给新值(这里代表o)
        }else if( item instanceof Object ){
           3. 判断这个值是否是对象(复合数据类型)
             new[k] = {} ; 
         deepCopy ( new[k] , item)     
        }else{
          4. 属于(基础数据类型)
           new[k] = item;
        }
     
      
        
      }
   }
 deepCopy (o , obj)
  
  5.修改新对象中的 o.msg.age=20  
  
   打印  obj.msg.age  和  o.msg.age
   结果2018 
   
   说明:深拷贝(复合数据类型),新对象(o)在堆内存开辟自己空间存储复制的数据,彼此修改不影响彼此。

浅拷贝多层(复合数据类型)如图:

Snipaste_2021-06-28_02-35-22.png

总结:

  • 浅拷贝: 拷贝(复合数据类型)的地址(注:这个地址存在栈里)指向同一个堆数据,彼此修改影响彼此。

  • 深拷贝 拷贝(复合数据类型),在堆开辟自己内存空间,存储复制好的"复合数据类型",彼此修改不影响彼此。

  • js中变量传值两种形式: (1)值传递:彼此修改没有影响(基础数据类型)

(2)引用传值:彼此的修改有影响(复合数据类型),也叫共享引用

注:所有的变量名都是栈