---
# System prepended metadata

title: JS淺層複製及深層複製
tags: [Javascript]

---

---
tags: Javascript
---

# JS淺層複製及深層複製

## JS物件參考
講到淺層複製及深層複製就會提到JS的物件參考，在JS裡傳值(`Call by value`)是複製的，將num的值複製到`num2`的新記憶體區域，例如以下
```javascript=
var num = 1;
var num2 = num;
```

而物件(陣列，函式)是利用`call by reference`，來看範例
```javascript=
var people = {name: "Joe"};
var people2 = people;
people2.name = "Amy";
console.log(people == people2); // true
console.log(people); // {name: 'Amy'}
console.log(people2); // {name: 'Amy'}
```

可以看到上面的範例，`people2`是參考`people`的記憶體位置，所以在`people2`更改`name`的值時，也會更改到`people`的值，因為他們**指向同一個記憶體位置**

如要重新附值，需要使用以下
```javascript=
var people = {name: "Joe"};
var people2 = people;
people2 = {name: "Amy"};
console.log(people == people2); // false
console.log(people); // {name: 'Joe'}
console.log(people2); // {name: 'Amy'}
```

但在函式裡面重新賦值，外面的變數都不會變，所以就是屬於 pass by value。

## 淺層複製 shallow copy

以下是淺層複製的範例，可以看到利用以下方法只能改變第一層，可以發現`members`都指向同個記憶體

```javascript=
var family = {
    name: 'Joe家',
    members: {
        father: '爸',
        mom: '媽',
        brother: '弟'
    }
}

var newFamily = {};
for (var key in family) {
    newFamily[key] = family[key];
}
newFamily.name = "Amy家";
console.log(family === newFamily); // false
newFamily.members.brother = "Timmy";
console.log(family, newFamily);
```

### jQuery

`var newFamily2 = jQuery.extend({}, family);`

### ES6

`var newFamily3 = Object.assign({}, family);`

## 深層複製 deep copy
先將物件轉成字串，再賦予給新變數，就可以將值複製到新的記憶體區域
```javascript=
var newFamily4 = JSON.parse(JSON.stringify(family))
newFamily4.name = "Amy家";
newFamily4.members.brother = "Timmy";
console.log(family === newFamily4); // false
```