본문 바로가기

개발 공부

얕은 복사, 깊은 복사

프론트엔드 개발을 하다 보면 객체나 배열을 복사해야 하는 경우가 자주 생깁니다.

특히 React에서 상태를 다룰 때, Redux에서 immutable하게 관리할 때, 복사 방식에 따라 버그가 발생할 수도 있습니다.

 

얕은 복사

얕은 복사는 객체나 배열을 복사할 때, 1단계까지만 복사하고 내부 참조는 공유하는 방식입니다.

const original = { user: { name: 'Alice' } };
const copy = { ...original };

copy.user.name = 'Bob';

console.log(original.user.name); // 'Bob'

 

  • ...original은 최상위 속성까지만 복사합니다.
  • user 객체는 여전히 같은 참조(주소)를 바라보고 있기 때문에, 하나를 수정하면 다른 것도 바뀝니다.

 

깊은 복사

깊은 복사는 객체나 배열의 모든 중첩된 값들까지 재귀적으로 완전히 복사합니다.

객체 내부의 모든 값들까지 재귀적으로 복사하여, 원본과는 완전히 독립적인 구조를 만듭니다.

const original = { user: { name: 'Alice' } };
const copy = JSON.parse(JSON.stringify(original));

copy.user.name = 'Bob';

console.log(original.user.name); // 'Alice'
  • JSON.parse(JSON.stringify(...))는 간단하지만 완벽한 방법은 아닙니다
  • undefined, function, Date, Map, Set 등의 값은 제대로 복사되지 않아요.
  • 예: Date는 문자열로 변환됨 → 타입 안정성 문제 발생

 

 

깊은 복사 방법

1. lodash 사용

import cloneDeep from 'lodash/cloneDeep';

const deepCopy = cloneDeep(original);

 

  • 실무에서 가장 안전하게 깊은 복사를 처리할 수 있는 방법 중 하나입니다.
  • 특히 Redux 상태를 다룰 때 많이 사용됩니다.

 

2. structuredClone (최신 브라우저 지원)

const copy = structuredClone(original);

 

 

  • 최신 브라우저에서 사용 가능
  • 순환 참조도 지원됨
  • Blob, File, Map, Set, ArrayBuffer 등도 복사 가능

 

 


 

정리

구분 얕은 복사 깊은 복사
복사 깊이 1단계만 복사 중첩된 모든 객체까지 재귀 복사
내부 참조 공유함 독립적인 새로운 객체 생성
방법 예시 Object.assign, spread (...) lodash.cloneDeep, structuredClone
실무 사용 예 단순 상태 변경 중첩된 상태 관리, 불변성 유지 필수 상황