先前有提到物件的特性是傳參考,但因為這個特性也會導致一些資料處理上的困擾,物件中有淺層複製跟深層複製的方法,來處理這個困擾。
原始物件資料
1 | var family = { |
淺層複製
for…in
使用 for...in
的方法取得物件資料,並可以得到以下的值。
1 | var newFamily = {}; |
key
: 會取到family
物件的第一層的屬性,也就是home
跟members
。family[key]
: 會取到home
的值跟members
的值(members
是物件)。
讓新的物件裡面的值等於原本物件裡面的值。
1 | var newFamily = {}; |
這時候再比對一下兩個物件,會得到 false,代表 newFamily 已經是新的物件了。
1 | var newFamily = {}; |
這時把新物件的 home
修改成別的值,並且看一下兩個物件的內容。
1 | var newFamily = {}; |
會發現 newFamily
第一層的 home
屬性被修改了,但 family
沒有,因為這兩個物件已經沒有關係了。
.
.
.
BUT! 人生最重要就是這個 BUT 了!
.
.
.
如果把 newFamily
裡面的 members
中的屬性改掉,
1 | var newFamily = {}; |
會看到 members
裡面的 dad
還是被改掉了,
原因是透過這樣的方式只能改變第一層的屬性內容,第二層資料內容還是以傳參考的形式,這個方式就叫做淺層複製,也有稱為淺拷貝。
其他方式寫法
jQuery 的寫法
使用 jQuery 的 extend 方法,前面先帶一個空物件,後面放入要複製的物件實字。
1 | var newFamily2 = jQuery.extend({}, family); |
ES6 的寫法
使用 ES6 寫法,使用 Object 的 assign 方法,前面帶一個空物件,後面放入要複製的物件實字。
1 | var newFamily3 = Object.assign({}, family); |
深層複製
為了不要有物件傳參考的特性,會先把資料轉型成字串,再轉型成物件,
先轉成字串
1 | console.log(family); //原本的物件 |
再轉成物件
再使用 JSON.parse 轉型成物件,這時候新的物件就跟原本的 family
物件沒有關聯了。
1 | console.log(JSON.parse(JSON.stringify(family))); |
兩者物件已無相聯性
將轉型後的物件賦予在新的變數上,並做比對,會發現是 false
。
1 | let newFamily4 = JSON.parse(JSON.stringify(family)); |