본문 바로가기
JavaScript

기본형 데이터 & 참조형 데이터

by bas96 2021. 6. 17.

기본형 데이터(숫자, 문자열, 불리언, null, undefiend ...)와 참조형 데이터(object - array, function, date, 정규표현식 ...)을 설명할 때 

일반적으로 기본형 데이터는 할당이나 연산 시 복제가 되고, 참조형 데이터는 참조가 된다고 알려져 있습니다. 

 

결론을 미리 말하자면 사실 기본형 데이터와 참조형 데이터 모두 복제를 합니다.

다만 기본형은 값이 담긴 주솟값을 바로 복제하는 반면 참조형은 값이 감긴 주솟값으로 이루어진 묶음을 가리키는 주소값을 복제합니다. 

 

복제에 대한 예시를 공부하기 전에 불변값과 가변값에 대한 개념을 먼저 알아보겠습니다.


불변 값

먼저 기본형 데이터는 모두 불변값입니다. 

 

var a = 6;
var b = 6;
a = 7;

 

이 경우 컴퓨터 내에서는 변수 영역 a의 값에 들어갈 6을 데이터 영역에서 찾습니다.

데이터영역에 6이 없을 경우 6이 들어 갈 데이터공간을 만들어 저장합니다.

 

그 다음 변수 b도 6이라는 데이터를 할당하였습니다. 그런데 앞서서 a를 선언할 때 데이터 영역에 6을 만들었죠?

이미 만들어 놓은 똑같은 값이 있으니 그 값을 그대로 재활용합니다.

 

앗 그런데 a 를 7로 바꾸려고 하네요! 

그러면 여기서! 기존에 6을 7로 바꾸는 것이 아니라, (6이 들어있는 데이터 영역에서 숫자를 바꾸는 것이 아니라)

데이터영역에 7일 찾아보고, 없으면 새로운 데이터 영역에 7을 만들고 그 7을 다시 할당하는 것입니다.

 

결국 데이터 영역에 있는 6과 7은 완전히 다른 데이터이고, 다른 값이므로 변경할 수 없습니다.

 

가변 값

그럼 참조형 데이터는 모두 가변 값일까요? 

기본적으로는 가변값일 경우가 다수이지만 설정에 따라 불가능한 경우도 있고, 아예 불변값으로 활용하는 방법(다음 포스팅 공부)도 있습니다.

 

기본형 데이터와 차이는 '객체의 변수(프로퍼티) 영역'이 별도로 존재한다는 점입니다.

 

위에서는 선언할 때 쓰이는 '변수 영역', 선언한 값이 들어가는'데이터 영역'이 쓰였는데 참조형에서는 '객체의 변수영역'이 추가됩니다.

 

변수 복사 비교

기본형 데이터와 참조형 데이터는 '복사'를 할 때 차이점이 잘 보입니다. 

 

아래의 예시로 그 차이점을 차이점을 알아보겠습니다.

 

var a = 10;
var b = a; 

var obj1 = {c: 10, d:'ddd'};
var obj2 = obj1;

b = 15;
obj2 = {c:20, d:'ddd'};

 

위의 코드는 a를 복사하여 b를 만들고, obj1을 복사하여 obj2를 만들었을 때입니다.

그리고 밑에서 b, obj2를 수정해주었습니다. 

 

회색으로 표현한 것은 5번째 줄까지 설명이고 

하늘색으로 수정된 것은 7,8번째 줄이 선언되면서 수정/추가 된 부분입니다.

 

이렇게 데이터 변경을 그려 확인해보니, a를 복사할 때 1001과 1002의 값이 @5001이라는 같은 값으로 복사되었습니다.

즉 값 10 자체가 아닌 10이 들어간 데이터주소 '@5001'이 복사된 것을 알 수 있습니다.

 

그래서 자바스크립트에서 '기본형은 값을 복사하고 참조형은 주솟값을 복사한다.'라고 그동아 알고 있었지만 사실 어떤 데이터 타입이든지간에 주솟값을 복사한다는 것을 알 수 있습니다.

(엄밀히 말하면 javascript의 모든 데이터타입은 참조형 이라는...)

 

그리고 obj2도 obj1의 값을 가르킨 '@5002'주소를 복사했습니다.

그런데 밑에서 새로운 객체를 할당해 주면서 값을 '@5006'으로 변경하였고, @5006에 들어갈 새로운 객체의 데이터를 만들어 주었습니다.

 

결국 

a !== b

obj1 !== obj2 

가 성립되게 되었습니다.

 

 

그런데 만약

var a = 10;
var b = a; 

var obj1 = {c: 10, d:'ddd'};
var obj2 = obj1;

b = 15;
obj2.c = 3;

이렇게 obj2안에 있는 객체의 c의 값만 바꾸어 주었더라면 어떻게 되었을까요? 

 

obj1과 똑같이 obj2도 @5002의 값을 가져오고, 주소@5002의 데이터인 주소@7001 ~?로 가서 c의 값인 @5001만 변경해서 새로운 @5009(가정 주소)와 같은 새로운 주소에 3을 저장하고 바꾸었을 것입니다. 

그럼 obj1 === obj2 겠죠? 

 

즉!! 참조형 데이터가 가변값이라 설명할 때 '가변'은 이렇게 데이터 자체를 변경하는 것이 아닌, 내부의 프로퍼티를 변경할 때만 성립합니다!

 

'JavaScript' 카테고리의 다른 글

동기 & 비동기(Promise, async/await)  (0) 2021.08.12
this  (0) 2021.06.24
실행 컨텍스트  (0) 2021.06.21
호이스팅  (1) 2021.06.19
불변 객체 | 얕은 복사 & 깊은 복사  (0) 2021.06.18