js實現(一層 / 多層)對象/數組的深拷貝

如何區分深拷貝與淺拷貝,簡單點來說,就是假設B複製了A,當修改A時,看B是否會發生變化,如果B也跟着變了,說明這是淺拷貝;如果B沒變,那就是深拷貝。
(上面的複製在程序中可以看做是賦值關係)

一、多層嵌套的深拷貝

1、封裝函數——遍歷的方式實現對象/數組深拷貝
// 深拷貝函數
function deepCopy(obj) {
      var result = Array.isArray(obj) ? [] : {};
      for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (typeof obj[key] === 'object') {
            result[key] = deepCopy(obj[key]);   //遞歸複製
          } else {
            result[key] = obj[key];
          }
        }
      }
      return result;
    }

    var obj = {
      a:1,
      b:{bb:2},
      c:[1,2,3]
    }
    var arr = [1,2,3,4,5,[22,33,[44,88]]]

    var copyObj = deepCopy(obj);
    // var copyObj = obj; // 如果不進行深拷貝,那麼修改copyObj的時候原先對象也會受到影響
    copyObj.b.bb = 111;
    console.log(obj)
    console.log(copyObj)

    var copyArr = deepCopy(arr);
    // var copyArr = arr;  // 如果不進行深拷貝,那麼修改copyArr的時候原先數組也受到影響
    copyArr[5].push(999)
    console.log(arr)
    console.log(copyArr)

2、JSON.parse/JSON.stringify方式——實現對象/數組的深拷貝

使用這個方法來進行深拷貝,如果對象中存在undefined、任意的函數以及 symbol 作爲對象屬性值時 JSON.stringify() 對跳過(忽略)它們進行序列化的隱患。
詳細閱讀:JSON.stringify() 九大特性

// 對象
var obj = {
      a:1,
      b:{bb:2},
      c:[1,2,3]
    }
var copyObj = JSON.parse( JSON.stringify(obj) ) // 這裏實現了對obj的深拷貝
copyObj.b.bb = 666
console.log(obj) // {a:1,b:{bb:2},c:[1,2,3]}
console.log(copyObj) // {a:1,b:{bb:666},c:[1,2,3]}

// 數組
var arr = [1, 2, [6], 7, [8, [9]]]
var copyArr = JSON.parse(JSON.stringify(arr)) // 這裏實現了對arr的深拷貝
copyArr[2].push(0)
console.log(arr) // [1, 2, [6], 7, [8, [9]]]
console.log(copyArr) // [1, 2, [6, 0], 7, [8, [9]]]

二、一層數組或對象的深拷貝

1、slice()—— 一層數組的深拷貝
var arr = [1, 2, 3]
var newArr = arr.slice()
arr.push(4)
console.log(arr) // [1, 2, 3, 4]
console.log(newArr) // [1, 2, 3]
2、concat()—— 一層數組的深拷貝
var arr = [1, 2, 3]
var newArr = arr.concat()
arr.push(4)
console.log(arr) // [1, 2, 3, 4]
console.log(newArr) // [1, 2, 3]
3、解構賦值—— 一層數組 / 對象的深拷貝
// 數組
var arr = [1, 2, 3]
var newArr = [...arr]
arr.push(4)
console.log(arr) // [1, 2, 3, 4]
console.log(newArr) // [1, 2, 3]
// 對象
var obj = { name: 'winne' }
var newObj = { ...obj }
obj.name = 'xf'
console.log(obj) // {name: "xf"}
console.log(newObj) // {name: "winne"}
4、Object.assign()—— 一層對象的深拷貝
var obj = { name: 'winne' }
var newObj = Object.assign({}, obj)
obj.age = 20
console.log(obj) // {name: "winne", age: 20}
console.log(newObj) // {name: "winne"}
5、filter()—— 一層數組的深拷貝
var arr = [1, 2]
var newArr = arr.filter((item) => {
  return true
})
arr.push(88)
console.log(arr) // [1, 2, 88]
console.log(newArr) // [1, 2]
6、map()—— 一層數組的深拷貝
var arr = [1, 2]
var newArr = arr.map((item) => {
  return item
})
arr.push(88)
console.log(arr) // [1, 2, 88]
console.log(newArr) // [1, 2]

參考原文:
https://www.cnblogs.com/renbo/p/9563050.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章