얕은 복사와 깊은 복사

KwonKusang·2021년 7월 29일
0

객체 복사는 크게 두 가지로 나뉜다. 얕은 복사(shallow copy)와 깊은 복사(deep copy)이다. 프로그래밍을 하는 사람이라면 객체를 다른 변수에 담기도 하며 많이 직면했을 문제이다.

소소한 경험

참고로 얕은 복사와 깊은 복사의 개념을 공부하게 된건 컴퓨터 공학부에 진학하고 처음 진행했던 개인 프로젝트였다. 카트라이더 미니게임을 제작하는 주제였는데 카트들의 부품을 객체로 선언하고 여러 개의 카트 객체에 온갖 부품을 다 달아줬었다. 나중에 보니 10개의 카트가 다 같은 파츠를 장착하고 있었다...이러니 얕은 복사와 깊은 복사를 공부해볼 수 밖에 없는 상황이었다...

얕은 복사(shallow copy)

let A = 3;
let B = A;
console.log(A, B)  // 3, 3

A = 5;
console.log(A, B)  // 5, 3

B에 A를 대입할 때 메모리에는 3이라는 숫자가 저장된다. 하지만 변수에 배열과 같은 참조값이 선언된다면 어떨까.

let A = [1,2,3,4,5];
let B = A;
console.log(A, B)  // [1,2,3,4,5] [1,2,3,4,5]

A[0] = 7;
console.log(A, B)  // [7,2,3,4,5] [7,2,3,4,5]

분명 변수 A에 저장된 배열의 첫번째 값만 바뀌었는데 변수 B의 값도 바뀐 것을 확인할 수 있다. 왜 그럴까?

배열을 예로 들자면, 변수 A에 [1,2,3,4,5]의 배열을 저장했을 때 변수 A의 메모리에는 배열의 첫번째 주소가 저장된다. 즉, 3과 같은 값 자체가 저장되는 것이 아니라 주소가 저장 되는 것이다.

A[0] = 7은 A에 저장된 주소로 들어가서 첫번째 데이터에 7 값을 저장한다.

때문에 변수 A, B에 저장된 데이터는 기존의 배열의 첫번째 주소인 것은 달라지지 않았다. 주소 안에 있는 데이터를 변경했을 뿐!!

깊은 복사(deep copy)

깊은 복사는 얕은 복사와 같이 주소(참조)를 복사하는 것이 아니다. 객체 자체를 새로 만들고 똑같은 데이터로 채워 넣는다.

let A = [1,2,3,4,5];
let B = JSON.parse(JSON.stringify(A));
console.log(A, B)  // [1,2,3,4,5] [1,2,3,4,5]

A[0] = 7;
console.log(A, B)  // [7,2,3,4,5] [1,2,3,4,5]

얕은 복사와는 달리 완전히 다른 주소를 서로 갖고 있기 때문에 데이터에 영향을 주지 않게 된다.

하지만 깊은 복사는 객체 자체를 새로 만들어내는 만큼 가장 많은 메모리와 늦은 처리 속도를 보인다.

얕은 복사 + 깊은 복사

말 그대로 얕은 복사와 깊은 복사를 섞어쓰는 개념이다. 참조 밑에 또 참조가 있을 경우 대표되는 상위 객체 하나만 깊은 복사를 하고 하위 객체들은 얕은 복사(참조만)를 하는 개념이다.

직접 사용해본 적은 없지만 얕은 복사의 범용성 문제와 깊은 복사의 늦은 처리 속도 문제를 타협하며 사용할 수 있을 것이다. 어떤 데이터를 사용하느냐에 따라 활용 방법이 다를 것이다.

profile
안녕하세요! 백엔드 개발자 권구상입니다.

0개의 댓글