기본형 데이터와 참조형 데이터
불변값
변수와 상수를 구분하는 성질은 '변경 가능성'입니다.
- 값을 변경할 수 있으면 변수
- 변경할 수 없으면 상수
- 변수와 상수를 구분 짓는 변경 가능성의 대상은 변수 영역 메모리입니다.
불변값과 상수는 다른 개념입니다.
- 불변성 여부를 구분할 때의 변경 가능성의 대상은 데이터 영역 메모리입니다.
- 불변값
- 기본형 데이터(숫자, 문자열, boolean, null, undefined, Symbol)
- 숫자와 문자열의 예시
// 1.
var a = 'abc';
a = a + 'def';
// 2.
var b = 5;
var c = 5;
b = 7;
- 변수 a에 데이터 할당 후 다른 데이터로 재할당 하는 경우
- a에 'abc'를 할당했다가 뒤에 'def'를 추가합니다.
- 'abc'와 'abcdef'는 완전히 별개의 데이터입니다.
- 기존의 'abc'가 'def'로 바뀌는게 아니라 새로운 데이터 영역에 'abcdef'를 만들어 그 메모리 주소를 a에 저장합니다.
- a에 'abc'를 할당했다가 뒤에 'def'를 추가합니다.
- b에 데이터 할당 후, 동일한 데이터를 c에 할당, 그 후에 b에 다른 데이터를 할당하는 경우
- b에 5를 할당하려 데이터 영역의 메모리 주소를 확인한다. 그리고 그 메모리 주소를 b변수의 값으로 할당합니다. 데이터 영역에 5라는 데이터가 없기 때문에 새로운 데이터 영역을 확보하고 5를 할당합니다.
- c에 5를 할당하려 데이터 영역의 메모리 주소를 확인합니다. b변수에 할당했던 메모리 주소에 5라는 데이터가 있으므로 해당 메모리 주소를 c로 할당하여 재활용합니다.
- b에 다시 7을 할당하려 데이터 영역의 메모리 주소를 확인한다.그 메모리 주소를 b의 값으로 할당합니다. 데이터 영역에 5라는 데이터가 없기 때문에 새로운 데이터 영역을 확보하고 7을 할당합니다.
결국 데이터 영역의 5나 7을 변경 시키지는 못합니다.
한 번 만들어진 값은 가비지 컬렉팅을 당하지 않는 한, 영원히 변할 수 없습니다.
이것이 바로 불변성의 성질입니다.
가변값
참조형 데이터를 변수에 할당하는 과정
var obj1 = {
a: 1,
b: 'bbb'
};
- 변수 영역
주소 | 1001 | 1002 | 1003 | 1004 | ... |
데이터 | 이름: obj1 값: @5001 |
- 데이터 영역
주소 | 5001 | 5002 | 5003 | 5004 | ... |
데이터 | @7103 ~ ? | 1 | 'bbb' |
- 객체 @5001의 변수 영역
주소 | 7103 | 7104 | 7105 | 7106 | ... |
데이터 | 이름: a 값: @5003 |
이름: b 값: @5004 |
- 변수 영역의 빈 공간(@1003)을 확보하고 그 주소의 이름을 obj1로 지정합니다.
- 임의의 데이터 저장 공간(@5001)에 데이터를 저장하려고 보니 여러 개의 프로퍼티로 이루어진 데이터 그룹(객체)입니다. 이 그룹 내부의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 확보하고, 그 영역의 주소(@7103 ~ ?)를 @5001에 저장합니다.
- @7103 및 @7104에 각각 a와 b라는 프로퍼티 이름을 지정합니다.
- 데이터 영역에서 숫자 1을 검색한다. 검색 결과가 없으므로 임의로 @5003에 저장하고, 이 주소를 @7103에 저장합니다. 문자열 ‘bbb’ 역시 임의로 @5004에 저장하고, 이 주소를 @7104에 저장합니다.
참조형 데이터가 기본형 데이터와의 차이는 '객체의 변수(프로퍼티) 영역'이 별도로 존재한다는 점입니다.
데이터 영역에 저장된 값들은 모두 불변값입니다.
하지만 객체의 프로퍼티(@5001) 변수 영역의 값은 다른 값으로 변경할 수 있기 때문에 불변mutable하지 않습니다.
(가변값입니다.)
참조형 데이터의 프로퍼티 재할당
var obj = {
a: 1,
b: 'bbb'
};
obj1.a = 2;
- 변수 영역
주소 | 1001 | 1002 | 1003 | 1004 | 1005 | ... |
데이터 | 이름: obj1 값: @5001 (변하지 않음) |
- 데이터 영역
주소 | 5001 | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | @7103 ~ ? | 1 | "bbb" | 2 |
- 객체 @5001의 변수 영역
주소 | 7103 | 7104 | 7105 | 7106 | 7107 | ... |
데이터 | 이름: a 값: @5005 |
이름: b 값: @5004 |
- obj1의 프로퍼티에 숫자 2를 할당하려고 합니다.
- 데이터 영역에서 숫자 2를 검색하지만 없으므로 빈 공간인 @5005에 저장하고 이 주소를 @7103에 저장합니다.
- 변수 obj1이 바라보고 있는 주소는 @5001로 여전히 그대로입니다.
참조형 데이터의 프로퍼티에 다른 참조형 데이터를 할당하는 경우 - 중첩객체nested object
var obj = {
x: 3,
arr: [3, 4, 5]
};
- 변수 영역
주소 | 1001 | 1002 | 1003 | 1004 | 1005 | ... |
데이터 | 이름: obj 값: @5001 |
- 데이터 영역
주소 | 5001 | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | @7103 ~ ? | 3 | @8104 ~ ? | 4 | 5 |
- 객체 @5001의 영역
주소 | 7103 | 7104 | 7105 | 7106 | 7107 | ... |
데이터 | 이름: x 값: @5002 |
이름: arr 값: @5003 |
- 배열 @5003의 영역
주소 | 8104 | 8105 | 8106 | 8107 | 8108 | ... |
데이터 | 이름: 0 값: @5002 |
이름: 1 값: @5004 |
이름: 2 값: @5005 |
- 변수 영역의 빈 공간(@1003)를 확보하고, 그 주소의 이름을 obj로 지정합니다.
- 임의의 데이터 공간(@5001)에 데이터를 저장하려 하지만, 여러 개의 변수와 값들을 모아놓은 그룹(객체)입니다. 이 그룹의 각 변수(프로퍼티)들을 저장하기 위한 별도의 변수 영역을 확보하고(@7103~?), 그 영역의 주소를 @5001에 저장합니다.
- @7103에 이름 x를, @7104에 이름 arr를 지정합니다.
- 데이터 영역에서 숫자 3을 검색하지만 없으므로 임의로 @5002에 저장하고 이 주소를 @7103에 저장합니다.
- @7104에 저장할 값은 배열로서 역시 데이터 그룹입니다. 이 그룹 내부의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고(@8104~?), 그 영역의 주소 정보(@8104~?)를 @5003에 저장한 다음, @5003을 @7104에 저장합니다.
- 배열의 요소가 총 3개이므로 3개의 변수 공간을 확보하고 각각 인덱스를 부여합니다. (0, 1, 2)
- 데이터 영역에서 숫자 3을 검색해서(@5002) 그 주소를 @8014에 저장합니다.
- 데이터 영역에 숫자 4가 없으므로 @5004에 저장하고, 이 주소를 @8105에 저장합니다.
- 데이터 영역에 숫자 5가 없으므로 @5005에 저정하고, 이 주소를 @8106에 저장합니다.
obj.arr[1] 값을 찾아봅시다.
1. obj검색 1: obj라는 식별자를 가진 주소를 찾습니다.
2. obj검색 2: @1003의 값이 주소이므로 해당 주소로 이동합니다. (@5001)
3. obj검색 3: @5001의 값이 주소이므로 해당 주소로 이동합니다. (@7103 ~ ?)
4. obj.arr검색 1: arr이라는 식별자를 가진 주소를 찾습니다. (@7104)
5. obj.arr검색 2: @7104의 값이 주소미으로 그 주소로 이동합니다. (@5003)
6. obj.arr검색 3: @5003의 값이 주소이므로 해당 주소로 이동합니다. (@8104 ~ ?)
7. obj.arr[1]검색 1: 인덱스 1에 해당하는 주소를 찾습니다. (@8105)
8. obj.arr[1]검색 2: @8105의 값이 주소이므로 해당 주소로 이동합니다. (@5004)
9. obj.arr[1]검색 3: @5004의 값이 숫자형 데이터이므로 해당 값인 4를 반환합니다.
@1003 -> @5001 -> (@7103 ~ ?) -> @7104 -> @5003 -> (@8104 ~ ?) -> @8105 -> @5004 -> 4 반환
객체 프로퍼티에 데이터 재할당 하기
obj.arr = 'str';
- 변수 영역
주소 | 1001 | 1002 | 1003 | 1004 | 1005 | ... |
데이터 | 이름: obj 값: @5001 |
- 데이터 영역
주소 | 5001 | 5002 | 5004 | 5005 | 5006 | |
데이터 | @7103 ~ ? | 3 | 4 | 5 | 'str' |
- 객체 @5001의 영역
주소 | 7103 | 7104 | 7105 | 7106 | 7107 | ... |
데이터 | 이름: x 값: @5002 |
이름: arr 값: @5006 |
- 배열 @5003의 영역
주소 | 8107 | 8108 | ... | |||
데이터 |
- @5006에 문자열 'str'을 저장하고, 그 주소를 @7104에 저장합니다.
- 그러면 @5003은 더이상 자신의 주소를 참조하는 변수가 하나도 없게 됩니다. → 이러한 경우를 참조 카운트가 0이라고 합니다.
- 참조 카운트가 0인 메모리 주소는 가비지 컬렉터Garbage Collector의 수거 대상이 됩니다.
- @5003의 참조 카운트가 0이 되면 @5003이 가리키고 있는 주소인 @8104 ~ ? 역시 참조카운트가 0이되어 GC의 대상이 되어 사라집니다.
출처 : 코어 자바스크립트
코어 자바스크립트 - YES24
자바스크립트의 근간을 이루는 핵심 이론들을 정확하게 이해하는 것을 목표로 합니다최근 웹 개발 진영은 빠르게 발전하고 있으며, 그 중심에는 자바스크립트가 있다고 해도 결코 과언이 아니
www.yes24.com
잘못되어 수정해야 하거나 피드백 주실 부분이 있으시면 언제나 환영입니다!
'도서 > 코어 자바스크립트' 카테고리의 다른 글
1장. 데이터 타입 (04. 기본형 데이터와 참조형 데이터 - 불변 객체) (0) | 2023.04.11 |
---|---|
1장. 데이터 타입(04. 기본형 데이터와 참조형 데이터 - 변수 복사 비교) (0) | 2023.04.10 |
1장. 데이터 타입 (01. 데이터 타입의 종류 ~ 03. 변수 선언과 데이터 할당) (0) | 2023.04.07 |