iT邦幫忙

0

淺拷貝Shallow Copy VS 深拷貝Deep Copy

  • 分享至 

  • xImage
  •  
  • 淺拷貝:指向同一個記憶體,原始值與新複製出來的值會連動
  • 深拷貝:為切斷之間的關聯性,複製即產生一個新的記憶體存放,所以當改動複製出來的值時,原始值就不會隨著被更動
  • 在js中,物件與陣列的複製皆屬於call by reference,所以如果以原始型別複製的方法,會有改寫原始值的問題
//原始型別如數值
let a = 7 
let b = a
a = 8
console.log(a, b) //8, 7
  • 由於原始型別複製是call by value(參考值,但創自己新的記憶體空間,指向的位置不同,所以改變a對b不會有影響)
  • 但在陣列複製是call by reference的情況下:
const players = ['emma', 'wilee', 'stella', 'jenny']
const team = players
team[3] = 'julia'
console.log(players, team)
// ['emma', 'wilee', 'stella', 'julia']
// ['emma', 'wilee', 'stella', 'julia']

  • team一改,players會跟著改,因為兩個物件指向同一個記憶體,基本上他們兩個是同一個東西,只是用不同名稱來稱呼同一個東西
  • 陣列如何切斷連動關係,實現深拷貝
const players = ['emma', 'wilee', 'howord', 'jenny']
const team2 = [...players]
const team3 = [].concat(players)
const team4 = Array.from(players)
cosnt team5 = players.slice()

team5[3] = 'julia'
team2[3] = 'cash'
team3[3] = 'miya'
team4[3] = 'sylar'
console.log(players, team2, team3, team4, team5);
// ['emma', 'wilee', 'stella', 'jenny']
// ['emma', 'wilee', 'stella', 'cash']
// ['emma', 'wilee', 'stella', 'miya']
// ['emma', 'wilee', 'stella', 'sylar']
// ['emma', 'wilee', 'stella', 'julia']

以上四種方法都可以讓複製值存放在新的記憶體,互相不干擾

  • 接下來看物件,同樣是call by reference,但深拷貝較複雜,易混淆
const person = {
name: 'julia'
age: 40
}

const driver = person
driver.gentle = 'female'

console.log(person, driver)
//可以看到原本的person跟driver連動
  • 用以下這兩種作法看是否能達到深拷貝
    • Object.assign()
    • ... spread syntax

const person = {
name: 'julia',
age: 40
}

const driver = Object.assign({}, person)
driver.name = 'stella'

const driver2 = {...person}
driver2.name = 'amy'
console.log(person, driver, driver2)

//看起來似乎有成功但...
  • 如果物件內又包一個物件(nested object),其物件仍指向同一個記憶體,所以這2種做法只達到最外層深拷貝,裡面還是一樣,
const julia = {
      name: 'julia',
      age: 40,
      social: {
        facebook: '@aaa',
        instagram: '@bbb'
      }
    }
    const dev = Object.assign({}, julia)
    dev.social.instagram = '@ccc'
    console.log(julia, dev);
   //可以看到兩個instagram連動 
   //...也是得到一樣連動的結果
const julia = {
      name: 'julia',
      age: 40,
      social: {
        facebook: '@aaa',
        instagram: '@bbb'
      }
    }
    const dev = JSON.parse(JSON.stringfy(julia))
    dev.social.instagram = '@ccc'
    console.log(julia, dev);

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言