얕은 복사와 깊은 복사

앞서 살펴봤듯이 참조형 데이터의 경우 새로운 데이터를 할당할 때 단순히 메모리 주소만 변경하는 경우가 아니라면 복사라는 개념을 사용해 각각의 변수들을 구분해서 관리해야합니다.

이러한 복사라는 개념은 겉의 표면만 복사하는 얕은 복사와 내부의 모든 참조까지 새로운 메모리로 복사하는 깊은 복사로 나누게 됩니다.

1. 참조형 데이터의 재할당 문제

Obejct.assign() 메소드나 전개 연산자(...)를 사용한 복사
const user = {
  name: '0soe',
  age: 12,
  emails: ['[email protected]]
}
const copyUser = user
console.log(copyUser === user) // true

user.age = 22
console.log(user) // {name: '0soe', age: 12, email: array(1)}
console.log(copyUser) // {name: '0soe', age: 12, email: Array(1)}
// user와 copyUser가 바라보는 메모리 주소가 같으므로 copyUser의 age도 함께 바뀌어 있음

copyUseruser는 같은 메모리 주소를 가르키고 있는 상태에서 user의 age속성의 값을 변경하는 경우 copyUser의 age속성의 값도 변경된 것을 확인할 수 있습니다.

2. 얕은 복사(Object.assign)

※Object.assgin({}, A ) 이용

const shallowUser = Object.assign({}, user)
console.log(shallowUser === user) // 값: false
console.log(shallowUser) // 값: {name: '0seo', age: 12, email: Array(1)}

※전개연산자 이용

const spreadUser = {...user}
console.log(spreadUser === user) // false
console.log(spreadUser) // {name: '0seo', age: 12, email: Array(1)}

얕은 복사의 문제점

user.emails.push('[email protected]')
console.log(user.emails === spreadUser.emails) // 값: true
//
// 같은 메모리 주소를 바라보기 때문에 값이 true가 반환됨

user의 emails은 배열데이터 입니다. 또한 배열데이터는 참조형 데이터 중에 하나로 user.emailsspreadUser.emails은 같은 메모리 주소를 바라보게 됩니다.

얕은 복사의 경우 객체데이터를 복사하는 것으로 그 안의 새로운 참조형데이터인 배열데이터까지 복사하지 못하기 때문에 user.emails을 변경하게 되면 spreadUser.emails도 변경되게 되는 것입니다.

3. 깊은 복사(Deep copy)