얕은 복사 & 깊은 복사

김희산·2023년 3월 24일
1

TIL

목록 보기
19/23

개요

깊은 복사 & 얕은 복사 이야기를 하기전에 먼저 자바스크립트의 데이터타입에 대해서 설명하려고 합니다.

자바스크립트가 제공하는 7가지 데이터 타입은 크게 원시 타입과 객체 타입으로 구분 할 수 있습니다.

이 두 가지 타입은 크게 세가지 측면에서 다릅니다.

  1. 원시 타입의 값, 즉 원시 값은 변경 불가능한 값이다. 이에 비해 객체 타입의 값, 즉 객체는 변경 가능한 값이다.

  2. 원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다. 이에 비해 객체를 변수에 할당하면 변수에는 참조 값이 저장된다.

  3. 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다. 이를 값에 의한 전달이라 한다. 이에 비해 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. 이를 참조에 의한 전달이라 한다.

값에 의한 전달(pass by value)와 참조에 의한 전달(pass by reference) 이 두가지 키워드에 집중하시면 됩니다.

여기서 "원시 값은 변경 불가능한 값이다"라고 하는데 이 말은 원시 값 자체를 변경 할 수 없다는 것이고 변수에 재할당을 할 수 없다는 것은 아닙니다.
변수는 재할당을 통해 언제든지 변경할 수 있습니다.

간단히 설명을 마쳤으니 본격적으로 얕은 복사와 깊은 복사의 예시를 보여드리겠습니다.


값에 의한 전달 (얕은 복사)

var score = 80;
var copy = score;

console.log(score); // 80
console.log(copy); // 80

score = 100;

console.log(score); // 100
console.log(copy); // ?

? 에 들어갈 정답은 80입니다.
copy = score; 에서 score는 변수값 80으로 평가되므로 copy 변수에도 80이 할당될 것입니다. 이때 새로운 숫자 값 80이 생성되어 copy 변수에 할당됩니다.

새로운 숫자 80이 생성된다는 것은 다른 메모리 공간에 80이라는 값이 할당이 된다는 것입니다. 두 개의 80이라는 값이 각각 다른 메모리 공간을 차지하고 있다고 보시면 됩니다.

이처럼 변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달된다. 이를 값에 의한 전달이라 한다.

참조에 의한 전달(깊은 복사)

객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어서(pass by reference) 전달이 됩니다.
예시와 함께 보시겠습니다.

var person = {
  name: 'Lee'
};

// 참조값을 복사(얕은 복사). copy와 person은 동일한 참조값을 갖는다.
var copy = person;

// copy와 person은 동일한 객체를 참조한다.
console.log(copy === person); // true

// copy를 통해 객체를 변경한다.
copy.name = 'Kim';

// person을 통해 객체를 변경한다.
person.address = 'Seoul';

// copy와 person은 동일한 객체를 가리킨다.
// 따라서 어느 한쪽에서 객체를 변경하면 서로 영향을 주고 받는다.
console.log(person); // {name: "Kim", address: "Seoul"}
console.log(copy);   // {name: "Kim", address: "Seoul"}

원시값을 할당한 변수는 원시 값 자체를 값으로 갖는다고 위에서 설명하였습니다. 하지만 copy = person; 에서 copy변수에는 person의 변수에 할당된 값이 아닌 person이 가리키고 있는 참조 값을 할당합니다.
따라서 copy와 person 두개의 변수는 같은 메모리 주소를 가리키고 있고 같은 객체를 참조하고 있습니다.

이것을 참조에 의한 전달이라고 합니다.
그러므로 만약 어느 한쪽에서 객체의 값을 동적으로 변경한다면 서로 같은 객체를 참조하고 있기 때문에 서로 영향을 주고 받는 것입니다.


정리

결국 "값에 의한 전달"과 "참조에 의한 전달"은 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서는 동일합니다. 다만 변수에 저장되어 있는 값이 값이냐,참조값이냐의 차이만 있을 뿐입니다.

따라서 이뜻을 놓고 보았을 때는 자바스크립트에서는 "값에 의한 전달"만 존재한다고 말할 수 있습니다. 참조값도 값이니까요.

크게 나누었을때 자바스크립트의 데이터 타입 두 가지를 예로 들어서 얕은 복사와 깊은 복사를 설명해보았습니다.

도움이 되셨다면 좋겠습니다.감사합니다.

참조 문서 : '모던 자바스크립트 Deep Dive'

profile
성공은 제로섬 게임이 아니라 주변인들과 함께 나아가는 것이다.

0개의 댓글