1. 程式人生 > 其它 >深拷貝 淺拷貝

深拷貝 淺拷貝

淺拷貝
⾸先可以通過 Object.assign 來解決這個問題,很多⼈認為這個函式是⽤來 深拷⻉的。其實並不是, Object.assign 只會拷⻉所有的屬性值到新的物件中,如果屬性值是物件的話,拷⻉的是地址,所以並不是深拷⻉。
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
另外我們還可以通過展開運算子 ... 來實現淺拷⻉
let a = {
age: 1
}
let b = { ...a }
a.age = 2
console.log(b.age) // 1

通常淺拷⻉就能解決⼤部分問題了,但是當我們遇到如下情況就可能需要使⽤ 到深拷⻉了--
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = { ...a }
a.jobs.first = 'native'
console.log(b.jobs.first) // native
淺拷⻉只解決了第⼀層的問題,如果接下去的值中還有物件的話,那麼就⼜回 到最開始的話題了,兩者享有相同的地址。要解決這個問題,我們就得使⽤深拷⻉了。

深拷貝
這個問題通常可以通過 JSON.parse(JSON.stringify(object)) 來解決。
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE

但是該⽅法也是有侷限性的:
·會忽略 undefined
·會忽略 symbol
·不能序列化函式
·不能解決迴圈引⽤的物件

  let obj = {
       a: 1,
       b: {
          c: 2,
          d: 3,
       },
  }
  obj.c = obj.b
  obj.e = obj.a
  obj.b.c = obj.c
  obj.b.d = obj.b
  obj.b.e = obj.b.c
  let newObj = JSON.parse(JSON.stringify(obj))
  console.log(newObj)

簡單來說深拷貝就是當遇到值是物件型別的時候就再執行一遍複製:

  function deepCopy (obj) {
      var result;
      //引用型別分陣列和物件分別遞迴
      if (Object.prototype.toString.call(obj) == '[object Array]') {
        result = []
        for (i = 0; i < obj.length; i++) {
          result[i] = deepCopy(obj[i])
        }
      } else if (Object.prototype.toString.call(obj) == '[object Object]') {
        result = {}
        for (var attr in obj) {
          result[attr] = deepCopy(obj[attr])
        }
      }
      //值型別直接返回
      else {
        return obj
      }
      return result
  }