1. 程式人生 > >利用遞歸實現深拷貝(常見面試題之一)

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

利用 實現思路 參數 面試題 由於 遞歸實現 但是 log 對象

淺拷貝和深拷貝的區別:

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

深拷貝: 將數據中所有的數據拷貝下來,對拷貝之後的數據進行修改不會影響到原數據


實現思路:

  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)

擴展

其他深拷貝方法:

b = JSON.parse( JSON.stringify( a ) )

不足:
由於JSON.stringify()這個方法是先將文明要拷貝的數據線轉換成字符串,來開辟一個新的地址用以儲存新的數據,但是這個方法無法轉化 function 和 undefined。


深拷貝的實現:可查看 手寫淺拷貝(常見面試題之一)

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