利用遞歸實現深拷貝(常見面試題之一)

淺拷貝和深拷貝的區別:

淺拷貝 : 只是將數據中全部的數據引用下來,依舊指向同一個存放地址,拷貝以後的數據修改以後,也會影響到原數據的中的對象數據數組

深拷貝 : 將數據中全部的數據拷貝下來,對拷貝以後的數據進行修改不會影響到原數據函數

 

實現思路:

  1. 將要拷貝的數據 obj 以參數的形式傳參
  2. 聲明一個變量 來儲存咱們拷貝出來的內容
  3. 判斷 obj 是不是引用類型數據,若是不是,則直接賦值便可( 能夠利用 obj instanceof Type 來進行判斷),
  4. 因爲用 instanceof 判斷array 是不是object的時候,返回值爲true, 因此咱們在判斷的時候,直接判斷obj 是不是Array 就可避免這個問題
  5. 根據判斷的不一樣類型,再給以前的變量賦予不一樣的類型: [ ] : { }
  6. 循環obj 中的每一項,若是裏面還有複雜數據類型,則直接利用遞歸再次調用copy函數
  7. 最後 將 這個變量 return 出來便可

代碼:

var obj = {   //原數據,包含字符串、對象、函數、數組等不一樣的類型
       name:"test",
       main:{
           a:1,
           b:2
       },
       fn:function(){
           
       },
        friends:[1,2,3,[22,33]]
   }

   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
        }    
      return newobj;    //函數必須有返回值,不然結構爲undefined
   }

    var obj2 = copy(obj)
    obj2.name = '修改爲功'
    obj2.main.a = 100
   console.log(obj,obj2)
相關文章
相關標籤/搜索