利用遞歸實現深拷貝(常見面試題之一)
阿新 • • 發佈:2018-12-01
利用 實現思路 參數 面試題 由於 遞歸實現 但是 log 對象
淺拷貝和深拷貝的區別:
淺拷貝 : 只是將數據中所有的數據引用下來,依舊指向同一個存放地址,拷貝之後的數據修改之後,也會影響到原數據的中的對象數據
深拷貝: 將數據中所有的數據拷貝下來,對拷貝之後的數據進行修改不會影響到原數據
實現思路:
- 將要拷貝的數據 obj 以參數的形式傳參
- 聲明一個變量 來儲存我們拷貝出來的內容
- 判斷 obj 是否是引用類型數據,如果不是,則直接賦值即可( 可以利用 obj instanceof Type 來進行判斷),
- 由於用 instanceof 判斷array 是否是object的時候,返回值為true, 所以我們在判斷的時候,直接判斷obj 是否是Array 就可避免這個問題
- 根據判斷的不同類型,再給之前的變量賦予不同的類型: [ ] : { }
- 循環obj 中的每一項,如果裏面還有復雜數據類型,則直接利用遞歸再次調用copy函數
- 最後 將 這個變量 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。
深拷貝的實現:可查看 手寫淺拷貝(常見面試題之一)
利用遞歸實現深拷貝(常見面試題之一)