javascript에서의 deep copy
# 객체를 깊은 복사
JavaScript에서 객체의 깊은 복사 (deep copy)를 수행하는 방법은 여러 가지가 있지만, 가장 간단하고 자주 사용되는 방법 중 하나는 `JSON.parse()`와 `JSON.stringify()`를 조합하는 것입니다. 이 방법은 객체를 JSON 문자열로 변환한 다음, 이 문자열을 다시 객체로 파싱하여 깊은 복사본을 생성합니다.
다음은 이 방법을 사용한 예시입니다:
```javascript
const original = {
name: 'John',
age: 30,
details: {
hobbies: ['reading', 'games'],
location: 'New York'
}
};
const deepCopy = JSON.parse(JSON.stringify(original));
// 이제 deepCopy는 original의 깊은 복사본입니다.
// original과 완전히 분리되어 있으며, 구조는 같지만 서로 다른 메모리를 차지합니다.
```
그러나 이 방법에는 몇 가지 한계가 있습니다:
- 메서드(함수)를 포함한 객체를 깊은 복사할 때는 메서드가 복사되지 않습니다.
- `Date` 객체, `RegExp` 객체 같은 특수 객체들이나 `undefined`, `Function` 같은 값들은 적절히 복사되지 않을 수 있습니다.
- 순환 참조가 있는 객체를 이 방법으로 복사하려고 하면 오류가 발생합니다.
만약 이러한 한계로 인해 문제가 발생한다면, Lodash 라이브러리 같은 외부 라이브러리의 깊은 복사 기능을 사용하는 것을 고려할 수 있습니다. Lodash의 `_.cloneDeep` 함수는 위에서 언급한 제한 사항들을 해결하고 더 복잡한 객체도 잘 처리할 수 있습니다.
```javascript
// Lodash 라이브러리의 예시
const _ = require('lodash');
const deepCopy = _.cloneDeep(original);
```
`JSON.parse(JSON.stringify())` 방법은 간단하고 빠르게 사용할 수 있지만, 위에서 언급한 한계점을 염두에 두고 사용해야 합니다. 더 복잡한 경우에는 Lodash와 같은 라이브러리를 사용하는 것이 좋습니다.
# 리스트를 깊은 복사
리스트를 깊은 복사하는 방법은 해당 리스트 내의 원소들이 기본 자료형(숫자, 문자열 등)일 경우와 객체나 배열 같은 참조 자료형일 경우에 따라 다를 수 있습니다. 기본 자료형만 포함된 리스트라면, 단순히 슬라이싱(`slice()`)이나 전개 연산자(`...`)를 사용해도 깊은 복사가 이루어집니다. 그러나 리스트의 원소 중 하나라도 객체나 또 다른 리스트(즉, 참조를 통해 데이터에 접근하는 타입)가 포함되어 있다면, 이러한 방법은 얕은 복사(shallow copy)만 수행하게 됩니다.
### 기본 자료형만 포함된 리스트 깊은 복사
기본 자료형만 포함된 리스트는 다음과 같이 간단히 깊은 복사할 수 있습니다:
```javascript
const original = [1, 2, 3, 4, 5];
const deepCopy = [...original];
// 또는
const deepCopyUsingSlice = original.slice();
```
### 참조 자료형 포함 리스트 깊은 복사
참조 자료형을 포함한 리스트의 경우, 가장 간단한 방법은 `JSON.parse()`와 `JSON.stringify()`를 사용하는 것입니다. 이 방법은 리스트를 문자열로 변환한 후 다시 파싱하여 깊은 복사본을 생성합니다:
```javascript
const original = [1, [2, 3], {a: 4, b: 5}];
const deepCopy = JSON.parse(JSON.stringify(original));
```
이 방법은 리스트 내의 객체나 다른 리스트도 포함하여 전체 구조를 깊게 복사하지만, 위에서 언급한 한계(함수, `undefined`, 순환 참조 등 특별한 경우 처리 불가)를 가지고 있습니다.
### 라이브러리 사용
복잡한 구조의 데이터나 특수한 경우를 처리해야 한다면, Lodash와 같은 라이브러리의 `_.cloneDeep` 함수를 사용하는 것이 좋습니다. 이 함수는 다양한 타입과 복잡한 구조, 순환 참조 등을 잘 처리할 수 있도록 설계되었습니다:
```javascript
const _ = require('lodash');
const original = [1, [2, 3], {a: 4, b: 5}];
const deepCopy = _.cloneDeep(original);
```
요약하자면, 리스트 내의 원소 타입과 복잡성에 따라 적절한 깊은 복사 방법을 선택해야 합니다. 단순한 경우에는 `JSON.parse(JSON.stringify())`를 사용할 수 있고, 보다 복잡한 상황에서는 Lodash 같은 라이브러리의 사용을 고려해야 합니다.
댓글
댓글 쓰기