바꿀 수 있으면 변수, 바꿀 수 없다면 상수이다. 둘을 구분하는 성질은 '변경 가능성'(한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지)이다.
기본형 데이터인 숫자, 문자열, boolean, null, undefined, Symbol은 모두 불변값이다.
var a = 'abc';
a = a + 'def';
var b = 5;
var c = 5;
b = 7;
b = 7;
은 기존에 저장된 5를 7로 변경하는 것이 아니라, 새로운 데이터 공간에 7을 만들어 그 주소를 변수 b에 새롭게 할당한다.참조형 데이터의 기본적인 성질은 가변값인 경우가 많지만 설정에 따라 변경 불가능한 경우도 있고, 아예 불변값으로 활용하는 방안도 있다.
var obj1 = {
a: 1,
b: 'bbb'
};
주소 | 100 | 101 | 102 | 103 | ... |
---|---|---|---|---|---|
데이터 | 이름 : obj1 값 : @201 |
주소 | 200 | 201 | 202 | 203 | 204 | ... |
---|---|---|---|---|---|---|
데이터 | @303 ~ ? | 1 | 'bbb' |
주소 | 302 | 303 | 304 | 305 | ... |
---|---|---|---|---|---|
데이터 | 이름 : a 값 : @203 | 이름 : b 값: @204 |
이처럼 참조형 데이터는 객체의 변수(프로퍼티) 영역이 별도로 존재한다. 위의 표를 보면 객체가 별도로 할애한 영역은 변수 영역이고, 데이터 영역은 기존의 메모리 공간을 그대로 활용한다. 데이터 영역에 저장된 값은 모두 불변값이고, 변수에는 다른 값을 얼마든지 대입할 수 있다.
자, 그럼 여기서 코드 한 줄만 추가해보자.
var obj1 = {
a: 1,
b: 'bbb'
};
obj1.a = 2;
주소 | 100 | 101 | 102 | 103 | ... |
---|---|---|---|---|---|
데이터 | 이름 : obj1 값 : @201 |
주소 | 200 | 201 | 202 | 203 | 204 | 205 | ... |
---|---|---|---|---|---|---|---|
데이터 | @303 ~ ? | 1 | 'bbb' | 2 |
주소 | 302 | 303 | 304 | 305 | ... |
---|---|---|---|---|---|
데이터 | 이름 : a 값 : @205 | 이름 : b 값: @204 |
a의 값을 1에서 2로 변경하는 코드이다. 여기서 값 1이 담긴 @203의 값이 2로 변경하는 것이 아니라, 새로운 공간(@205)에 2를 담아 a 변수(@303)의 주솟값을 2가 담긴 주소로 변경해준다.
즉, 새로운 객체가 만들어지는 것이 아니라, 기존의 객체 내부의 값만 바뀐다.
var obj = {
x: 3,
arr: [3, 4, 5]
};
주소 | 100 | 101 | 102 | 103 | ... |
---|---|---|---|---|---|
데이터 | 이름 : obj 값 : @201 |
주소 | 200 | 201 | 202 | 203 | 204 | 205 | ... |
---|---|---|---|---|---|---|---|
데이터 | @303 ~ ? | 4 | 5 | @401 ~ ? | 3 |
객체 @201의 변수 영역
주소 | 302 | 303 | 304 | 305 | ... |
---|---|---|---|---|---|
데이터 | 이름 : x 값 : @205 | 이름 : arr 값: @204 |
배열 @의 변수 영역
주소 | 400 | 401 | 402 | 403 | ... |
---|---|---|---|---|---|
데이터 | 이름 : 0 값 : @205 | 이름 : 1 값: @202 | 이름 : 2 값: 203 |
// 만약 아래의 코드가 실행될 경우, obj.arr[1];
@100 ➡️ @201 ➡️ @303 ~? ➡️ @304 ➡️ @204 ➡️ @401 ~? ➡️ @402 ➡️ @202 ➡️ 4 변환
// 만약 arr 배열을 문자열로 변환할 경우, obj.arr = 'str';
새로운 공간에 'str'인 문자열을 저장하고, 그 주소를 @304에 저장한다. 더 이상 자신을 참조하는 변수가 하나도 없게 되면 그 대상(@204, @401, @402, @403)은 가비지 컬렉터의 수거 대상이 된다. 수거된 메모리는 새로운 값을 할당할 수 있는 빈 공간이 된다.
참조 카운트 : 어떤 데이터에 대해 자신의 주소를 참조하는 변수의 개수
코드를 쓸 줄만 알았지, 메모리가 할당되는 과정은 이렇게 되는구나! obj.arr[1]
을 할 경우 사람의 입장에선 되게 쉬운 개념이지만 컴퓨터는 꽤 여러 주소의 메모리 공간을 거쳐서 찾아내는구나! 하고 깨달았다.
조금 더 불변값과 가변값에 대해 깊게 이해할 수 있게 되었다!