딥 복사(deep copy)란 복사 대상 객체 내부에 포함된 모든 중첩 객체까지 하나하나 새롭게 복제하는 것을 의미합니다. 이렇게 만들어진 복사본과 원본 객체는 아무것도 공유하지 않기 때문에, 복사본은 완전히 독립적인 새로운 객체가 됩니다.
반면 얕은 복사(shallow copy)는 최상위 속성만 복사하고 내부의 중첩 객체는 원본과 참조를 공유하기 때문에, 한쪽을 수정하면 다른 쪽에도 영향을 미치게 됩니다.
JSON을 활용한 가장 간단한 딥 복사 방법
가장 손쉬운 방법은 객체를 JSON.stringify()로 문자열로 변환한 뒤, 다시 JSON.parse()를 통해 자바스크립트 객체로 되돌리는 것입니다. 다만 이 방식은 객체 내부에 정의된 메서드(함수)는 복사할 수 없다는 한계가 있습니다.
예제
let obj = {
foo: 1,
bar: { baz: 'test' }
}
let newObj = JSON.parse(JSON.stringify(obj));
obj.bar.baz = 20;
console.log(obj);
console.log(newObj);실행 결과
{ foo: 1, bar: { baz: 20 } }
{ foo: 1, bar: { baz: 'test' } }실행 결과를 보면 원본 obj의 중첩 속성인 bar.baz 값을 20으로 변경했음에도, 복사본인 newObj는 여전히 기존 값 'test'를 유지하고 있습니다. 이는 두 객체가 서로 아무런 참조도 공유하지 않는 완전히 독립적인 객체임을 보여주며, 딥 복사가 성공적으로 수행되었음을 의미합니다.
참고: JSON 방식의 한계와 대안
JSON 직렬화 방식은 간편하지만 다음과 같은 제약이 있습니다.
- 함수(메서드)나 undefined, Symbol 값은 복사되지 않고 사라집니다.
- Date 객체는 문자열로 변환되며, Map, Set 같은 자료구조는 제대로 복원되지 않습니다.
- 순환 참조(circular reference)가 있는 객체는 에러를 발생시킵니다.
이러한 경우에는 최신 자바스크립트 환경에서 제공하는 structuredClone() 메서드를 사용하는 것이 좋습니다. 이 함수는 함수를 제외한 대부분의 데이터 타입과 순환 참조까지 안전하게 처리할 수 있습니다.