> For the complete documentation index, see [llms.txt](https://docs.sysout.co.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sysout.co.kr/web/develop-page/js/syntax/object-copy.md).

# Object copy

## Deep Copy vs Shallow Copy

자바스크립트에서 데이터를 복사하는 방법은 두 가지가 있다.

* 얕은 복사(Shallow Copy) - 참조만 복사, 객체는 유지
* 깊은 복사(Deep Copy) - 참조, 객체 모두 복사

좋고 나쁨은 없으며, 개념을 이해하고 원하는 상황에서 사용하는 것이 중요하다.

## Shallow Copy

얕은 복사는 객체는 유지하며 참조만 복사한다. 예를 들면 자동차는 그대로 두고 자동차 키만 복제하는 것과 같다.

```javascript
const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = monster;//shallow copy
console.log(monster, copyMonster);
```

각각 출력하면 객체의 정보가 잘 나온다.

<div align="left"><figure><img src="/files/5ffxGZ5kEXBYJ3yfFVc6" alt=""><figcaption></figcaption></figure></div>

하지만 이 둘은 동일한 객체이며 단지 참조만 복사된 형태이다.

```javascript
console.log(monster === copyMonster);//true
```

<div align="left"><figure><img src="/files/urcqK2GM7MSURq4oTTsf" alt=""><figcaption></figcaption></figure></div>

### 사용하는 경우

배열 등을 함수에서 처리할 때 shallow copy를 사용하면 추가 반환 등의 필요가 없다.

```javascript
const increase = function(arr) {
    for(let i=0; i < arr.length; i++){
        arr[i] += 1;
    }
};

const numbers = [10, 20, 30, 40, 50];
increase(numbers);

console.log(numbers);//[11, 21, 31, 41, 51]
```

위 코드는 increase 함수에서 추가적인 반환 없이 외부 배열의 값을 변경하는 예제이다. 배열은 하나만 두고 참조를 복사하였기 때문에 원본 배열에 접근하여 작업을 처리할 수 있다.

<div align="left"><figure><img src="/files/OAguo0m7njrAoJppX0RH" alt=""><figcaption></figcaption></figure></div>

## Deep Copy

Shallow Copy만으로는 배열 혹은 객체가 복제되었다고 보기 어렵다. 일반적으로 복제 혹은 복사라고 하면 참조 뿐만 아니라 대상까지도 복사 되는 경우를 의미할 때가 많으며 코드를 작성할 경우도 이는 마찬가지이다.

### 수동 복사

직접 객체를 만들고 데이터를 지정하여 복사하는 방법이다. 권장하지 않는다.

```javascript
const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = {
    no : monster.no,
    name : monster.name,
    type : monster.type
};

console.log(monster === copyMonster);//false
```

<div align="left"><figure><img src="/files/KmGgRHg7Sg8MFangawD4" alt=""><figcaption></figcaption></figure></div>

### JSON 복사

JSON 변환 명령을 사용한 복사이다.

* JSON.stringify() - 객체를 JSON 문자열로 변환
* JSON.parse() - JSON 문자열을 객체로 변환

기존 코드에서는 비교적 간편하게 세부 속성까지 복사가 되므로 자주 사용하는 코드 중 하나이다.

```javascript
const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = JSON.parse(JSON.stringify(monster));

console.log(monster === copyMonster);//false
```

### Object.assign()

ES6의 Object.assing() 함수를 이용하는 방법이다. 이 명령은 서로 다른 객체를 병합(merge)할 수 있는 명령이지만 빈 객체와 합치면 기존 객체가 깊은 복사가 되는 효과가 발생한다.

```javascript
const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = Object.assign({}, monster);

console.log(monster === copyMonster);//false
```

### rest

구조 분해 할당 문법에서 사용할 수 있는 rest 연산이 있다. 객체에서 특정 항목을 제외한 나머지 항목만 추출하는 명령이지만 이를 이용해도 객체의 깊은 복사가 가능하다.

```javascript
const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};
const {...copyMonster} = monster;

console.log(monster === copyMonster);//false
```

{% hint style="info" %}

### <mark style="color:blue;">rest 연산</mark>

rest 연산을 사용하면 특정 항목에 대한 제거가 가능하다.

다음 코드는 monster 객체에서 no를 제외한 나머지 항목을 추출하여 객체를 만드는 코드이다.

```javascript
const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};
const {no, ...copyMonster} = monster;
```

{% endhint %}
