면접에서 깊은 복사 vs 얕은 복사에 대한 아주 기초적인 질문을 받았다. 알고 있다고 생각했는데 제대로 대답하지 못했다. 정리할 필요성을 느꼈다.
깊은 복사와 얕은 복사가 생기는 이유인 기본형 vs 참조형 데이터의 차이에 대해 정리해보자!
(인프런의 Javascript 핵심 개념 알아보기 - JS Flow 강의를 참고했습니다.)
자바스크립트 자료형에는 크게 두가지가 있다.
두가지 모두 선언(declaration)과 할당(assignment)의 과정을 거친다.
두 자료형의 차이는 할당과정에 있다.
Primitive Type은 값을 그대로 할당하고, Reference Type은 값이 저장된 주소값(참조위치)을 할당한다.
var a = 10;
위 코드는 아래 과정으로 나눌 수 있다.
var a; // declaration
a = 10; // assignment
아래 그림과 같이 변수 a에 매칭할 주소값(500)을 확보하고, 주소값에 실제값을 할당한다.
a의 값이 바뀌면 공간을 확보하여 새 데이터를 공간에 할당하고, a변수의 값이 가리키는 주소값을 바꿔준다.
a = 15;
새로운 변수 b를 선언하고 b에 a를 할당하면
var b = a;
console.log(b===a) // true
이 때, b와 a는 일치한다.
b에 새로운 값을 할당하면 b 주소값에 새로운 값이 할당되고 a에는 변화가 없다.
b = 20;
console.log(b===a) // false;
이 때, b와 a는 일치하지 않는다. 즉 b의 변경에 a가 영향받지 않는다.
참조 자료형은 선언과 할당의 과정은 똑같으나 , 참조과정을 한번 더 거친다.
var obj = {
a: 1,
b: 'abc',
};
변수 obj에 매칭할 주소값(600)을 확보한다. 이 때, 객체는 데이터를 한번에 담을 수 없으므로 우선 해당 주소값에 여러 공간을 확보해둔다.
확보해둔 공간에 각각 객체의 데이터들을 기본자료형처럼 선언, 할당한다.
이처럼 참조형 데이터는 참조과정을 한번 더 거쳐간다.
객체 내부의 데이터를 변경해도, 객체의 주소값은 바뀌지 않는다.
obj.a = 2;
obj 내부의 a의 주소값은 바뀌지만 obj의 주소값은 바뀌지 않는다.
새로운 객체 obj2에 obj를 할당하면 다음과 같이 obj의 주소값을 공유하게 된다.
var obj2 = obj;
obj2 내부 데이터를 변경하면 같은 주소값을 참조하고 있는 obj도 영향을 받게 된다.
obj2.a = 3;
console.log(obj.a) // 3;
console.log(obj === obj2) // true;
obj2.a의 값을 변경하면 obj.a도 같이 바뀐다.
=
로 복사했을 때 , 기본형 데이터는 깊은 복사가 되고 참조형 데이터는 얕은 복사가 된다.