깊은 복사와 얕은 복사

·2023년 4월 6일
0

Today I Learned

목록 보기
97/114
post-thumbnail

객체를 복사하는 방법

자바스크립트에서 객체를 복사하는 방법은 2가지다. 얕은 복사와 깊은 복사. 둘 다 복사이기 때문에 원본 객체와 다른 객체가 된다.

  1. 얕은 복사
// 원본
const obj = { year: 2023, more: { month: 4 } };
// 얕은 복사
const shallow = {...obj}
// 다른 객체인가?
console.log(obj === shallow)

console.log로 확인해보면, 내용이 같지만 다른 객체라는 것을 확인할 수 있다.

그러면 shallow의 프로퍼티를 변경해보자.

// 원본
const obj = { year: 2023, more: { month: 4 } };
// 얕은 복사
const shallow = {...obj}

shallow.year = 2022
shallow.more.month = 5

다시 확인해보자.

분명 다른 객체인데 shallow 내 중첩 객체가 바뀌니까 원본의 중첩 객체 내용도 변경됐다. 여기서 얕은 복사의 특징을 확인할 수 있다. 얕은 복사는 중첩된 객체까지는 복사하지 못한다. 프로퍼티를 변경하기 전에 같은 내용으로 보였던 건, 복사본이 원본의 중첩 객체를 참조하고 있었을 뿐이다.

얕은 복사는 중첩 객체로 들어가기 전 계층까지만 복사하고, 중첩 객체는 참조함

  1. 깊은 복사
// 원본
const obj = { year: 2023, more: { month: 4 } };
// 깊은 복사
const deep = JSON.parse(JSON.stringify(obj))

deep.year = 2030
deep.more.month = 12;

이번엔 깊은 복사를 확인해보자. 참조를 끊고 아예 다른 객체를 생성하기 위해서 객체를 문자열로 바꾼 후 다시 자바스크립트 객체로 변환했다.

얕은 복사와는 달리 중첩 객체까지 모두 복사되어서 완전히 다른 객체로서 사본을 만들 수 있다. 사본의 중첩 객체는 원본의 중첩 객체를 참조하지 않았다.

깊은 복사는 중첩 객체까지 복사한다. 완전히 다른 사본임

  1. 결론
  • 중첩 객체까지 복사할 필요가 없다면 '얕은 복사'를 하면 됨
  • 중첩 객체까지 복사해야 하면 '깊은 복사'를 해야만 함
  1. 그런데 왜 이러는 걸까?

객체를 할당한 변수에 담기는 것은 값이 아니라 '객체 값이 저장된 또다른 메모리 주소를 가리키는 참조'이기 때문이다.

일반적인 복사를 하면 참조값을 복사해오는 것이기 때문에 엄밀히 말해 복사본이라고 할 수 없다. 변수 이름이 다를 뿐 같은 메모리 주소를 가리킬 테니까.

그러니 참조를 끊고 진짜 복사본을 만들기 위해서는 얕은 복사 또는 깊은 복사를 해야만 하는 것이다.

  1. 추가 사항

얕은 복사와 깊은 복사를 나누는 기준이 2가지가 있다.

  1. 객체를 할당한 변수를 다른 변수에 할당하는 것을 '얕은 복사', 원시형 데이터를 할당한 변수를 다른 변수에 할당하는 것을 '깊은 복사'로 칭하는 경우 (이 경우에는 참조값을 복사하는 것이 곧 얕은 복사고 값 자체를 복사하는 것이 깊은 복사다)
  2. 중첩 객체를 제외한 계층의 프로퍼티만 복사하는 것을 '얕은 복사', 중첩 객체까지 복사하는 것을 '깊은 복사'로 칭하는 경우

이 글은 2번째를 기준으로 했다.

profile
⛰ 프론트엔드 개발 공부 블로그

0개의 댓글