深拷贝和浅拷贝原理

基础数据类型:

  string、number、null、undefined、boolean、symbol

引用数据类型:

  函数、对象、数组

产生原因:

  基本类型是按值访问的,引用类型是按引用访问

  1、基本类型的存储是放在栈区的

 

  2、引用类型的存储是放在堆内存中的

 

   当引用类型进行赋值的时候,JavaScript不允许直接访问内存中的位置,也不能直接操作对象中的内存空间。操作对象是直接操作对象的引用,而不是整个对象,所以就会出现深拷贝、浅拷贝的问题

 

 

  浅拷贝只复制指向某个对象的指针,而不复制对象本身,相当于是新建了一个对象,该对象复制了原对象的指针,新旧对象还是共用一个内存块,

  深拷贝是新建一个一模一样的对象,该对象与原对象不共享内存,修改新对象也不会影响原对象

浅拷贝实现方式:

  1、对象使用Object.assign(target, source)方法

     let  testDeepObj2 =   Object.assign({},testDeepObj1);

  testDeepObj1对象中有引用类型的话,就是浅拷贝

  2、数组使用slice()、concat()方法

        var arr = ['jack',25,{hobby:'tennise'}];
        let arr1 = arr.slice()
        arr1[2].hobby='rose'
        arr1[0]='rose'
        console.log( arr[2].hobby) //rose
        console.log( arr[0]) //jack    

  

深拷贝实现方式:

 

   1.JSON.parse(JSON.stringify()),这种方式的缺点是当对象里面有函数的话,深拷贝后,函数会消失

     let arr1 = JSON.parse(JSON.stringify(arr))

  2、手写递归函数实现深拷贝

function copy(obj){
        let newobj = null;   //声明一个变量用来储存拷贝之后的内容
        
     //判断数据类型是否是复杂类型,如果是则调用自己,再次循环,如果不是,直接赋值即可,
     //由于null不可以循环但类型又是object,所以这个需要对null进行判断
        if(typeof(obj) == 'object' && obj !== null){ 
        
	//声明一个变量用以储存拷贝出来的值,根据参数的具体数据类型声明不同的类型来储存
            newobj = obj instanceof Array? [] : {};   
            
	//循环obj 中的每一项,如果里面还有复杂数据类型,则直接利用递归再次调用copy函数
            for(var i in obj){  
                newobj[i] = copy(obj[i])
            }
        }else{
            newobj = obj
        }    
        console.log('77',newobj)
      return newobj;    //函数必须有返回值,否则结构为undefined
   }

  

 

参考文献:https://blog.csdn.net/qq_34645412/article/details/106327826

 

posted @ 2020-08-24 12:04  嘟嘟兜  阅读(642)  评论(0)    收藏  举报