剛開始接觸到 JS 的時候,讀了相關書籍時,看到有關淺拷貝跟深拷貝的問題。
當下不是有很強烈的感覺,畢竟沒碰過。
直到我開始寫 Vue 時,要處理資料這一塊,使用了 prop
傳值到子 component 。
意外發現不需要 emit
回父 component ,這時才慶幸那時候知道 JS 有 call by reference 這個問題。
既然如此,如果想要將資料拷貝,有幾種方式。
JSON
首先是使用 JSON 拷貝方式:
1 | let newObj = JSON.parse(JSON.stringify(oldObj)) |
使用 JSON 去拷貝,能良好的將你拿到的資料拷貝一份新的,無論他有幾層都可以。
缺點是因為 JSON 不能拷貝 function ,所以遇到 function 只能另闢蹊徑。
淺拷貝
如果你的資料只有一層,使用淺拷貝即可
array
1 | let a = [1, 2, { x: 1 }] |
object
1 | let c = { x: 1, y: { w: 1, v: 2 } } |
以上這兩種方式只能拷貝第一層,
第二層之後的還是會受 call by reference 影響,
即 a[2]
和 b[2]
、 c.y
和 d.y
,
其指向為同一位址。
深拷貝
如果有兩層的資料,又有 function 需要被拷貝,就要使用深拷貝了
1 | function deepCopy(inputData) { |
這個 function 用到了遞迴,當遇到非 object 或 array 就會直接回傳輸入值,
如果是 object 或 array,就會創立一個新的 {} 或 [] 並再檢查一次