js中對象和數組的淺拷貝與深拷貝(ES6、前端面試常用)

在ES6中擴展操作符(…)與Object.assign()中複製是淺拷貝,所謂的淺拷貝和深拷貝:

淺拷貝,是在拷貝過程中,遍歷時那部分爲對象/數組類型指向原來的地址。即修改其中任意的值,另一個值都會隨之變化

深拷貝,則是完全開闢新的內存地址。即將對象及值複製過來,兩個對象修改其中任意的值另一個值不會改變

1、淺拷貝

淺拷貝: 只做一個最外層的拷貝. 如果拷貝的對象是引用型數據類型,則意味着交出了內存地址,因而在淺拷貝成功的對象身上對引用型數據進行修改時,就會影響到 原來的拓本

let obj = {
    a: 1,
    b: [1, 2, {a:3}],
    c: {a:3}
}
obj.c.a = 4

let obj1 = {
    a: obj.a,
    b: obj.b
}
obj1.b.push(1) // 切記不要 
obj1.b = 123 這樣是重新賦值 不是改變原地址的對象
console.log(obj.b) //將會被改變


ES6方法:
let obj2 = Object.assign({},obj)
console.log(obj2)  //  {a: 1,b: [1, 2, {a:3}],c:{a:4}

let obj3 = {...obj}
conosle.log(obj3) //  {a: 1,b: [1, 2, {a:3}],c:{a:4}

 

2、深拷貝

深拷貝: 裏裏外外全部拷貝,完全複製,保證引用型數據 依舊是引用型,但不拿地址,只模仿你的面,因此擴展上沒有問題,不會衝突

let obj1 = {
    a: 1,
    b: [1, 2, {a:3}],
    c: {a:3}
} 
//完全複製 完美複製 但是一個一個去複製,太麻煩啦 我們來一個專門深淺複製的函數

obj1.c.a = 4

let obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj2)  //    {a: 1,b: [1, 2, {a:3}],c:{a:3}

 

自制深複製函數

1.需求  參數1傳入拓本  輸出拷貝品
 let obj = { //拓本
     a: 1,
     b: [1,2,3,{a: "我"}],
     c: {d: 5}
 }
 function extend (o1) {
     var obj1 = {}
     if (o1 instanceof Array) { //判斷對象是否是數組
         obj1 = []
     }
     for(var key in o1){
         var value = o1[key] // 拓本中的值 
          // value內還有引用型數據&& value不爲 null 則 需要對value這個對象 再進來 深拷貝一份 返回出來深拷貝後的值 
         // obj1[key] = extend(value) 
         if(typeof value ==="object" && value !== null){
             obj1[key] = extend(value) 
         }else{
             obj1[key] = value
         }
     }
     return obj1
 }

let obj2 = extend(obj)  // 深拷貝測試
obj2.b.push("最後")
console.log(obj2)
console.log(obj) // 深拷貝 不影響拓本  淺拷貝 拓本一起變
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章