淺層複製及深層複製
淺層複製 (Shallow Copy)
1 2 3 4 5 6 7 8 9 10 11 12
| var family = { name: '小明家', members: { dad: '老爸', mom: '老媽', ming: '小明' } }; var newFamily = {}; for (var key in family){ console.log(key) }
|
這裡可以看到 key
的值其實就是 family
的第一層屬性。
所以我們可以利用這種方式做到第一層的複製。 如下 ↓
1 2 3 4 5 6 7 8 9 10 11 12 13
| var family = { name: '小明家', members: { dad: '老爸', mom: '老媽', ming: '小明' } }; var newFamily = {}; for (var key in family){ newFamily[key] = family[key]; } console.log(newFamily);
|
這樣就可以利用 key
依序把第一層的屬性 name
,members
取出來放到 newFamily
裡面。
這裡 family
跟 newFamily
就不會是在同一個位址上,我們可以換一種方式來測試。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var family = { name: '小明家', members: { dad: '老爸', mom: '老媽', ming: '小明' } }; var newFamily = {}; for (var key in family){ newFamily[key] = family[key]; }
newFamily.name = '杰倫家'; console.log(family); console.log(newFamily);
|
會出現下面這樣的結果 ↓
由此可知它們已經完全沒有關係了。((但是只限第一層喔!
原因是為什麼呢? 我們接著看下去 ↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var family = { name: '小明家', members: { dad: '老爸', mom: '老媽', ming: '小明' } }; var newFamily = {}; for (var key in family){ newFamily[key] = family[key]; }
newFamily.name = '杰倫家'; newFamily.members.ming = '杰倫'; console.log(family); console.log(newFamily);
|
結果如下 ↓
原因是 newFamily
宣告了新物件也把 family
第一層的屬性依序加進去,但是 members
本來就是一個物件了!所以你把 members
丟到 newFamily
其實也是把一個參考位址丟過去。(在 ‘取值&取址’章節 有講到)
這種方式就叫做「淺層複製」也能稱為「淺拷貝」。
上面講的是基本原理,現在除了 for in
之外也有其他方法可以很快速的做出這樣的淺層複製,讓我們繼續看下去。
第一種是利用 jQuery 的方式,語法如下 ↓
1
| var newFamily = jQuery.extend({}, family);
|
第二種是新的 ES6 才有的語法 ↓
1
| var newFamily = Object.assign({}, family);
|
上述的兩種方法都能夠做到淺層複製的效果喔!
深層複製 (deep copy)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var family = { name: '小明家', members: { dad: '老爸', mom: '老媽', ming: '小明' } };
// 深層複製語法 ↓ var newFamily = JSON.parse(JSON.stringify(family));
newFamily.name = '杰倫家'; newFamily.members.ming = '杰倫'; console.log(family) console.log(newFamily); console.log(family === newFamily);
|
原理是把 family
裡面的所有東西轉成字串之後,本身的記憶體參考位址會消失,然後再轉回物件的時候,又會再指向新的一個記憶體參考位址。
所以利用著這個方式就可以做到「深層複製」也能稱為「深拷貝」。