본 포스팅은 코어 자바스크립트 책을 읽고 정리한 내용입니다.
var obj1 = {
a : 1,
b : 'bbb
};
주소 | ... | 1002 | 1003 | 1004 | ... |
---|---|---|---|---|---|
데이터 | 이름 : obj1 값 : 5001 |
주소 | 5001 | 5002 | 5003 | 5004 | 5005 |
---|---|---|---|---|---|
데이터 | @7001 ~ ? | 1 | 'bbb' |
주소 | 7001 | 7002 | 7003 | 7004 | 7005 |
---|---|---|---|---|---|
데이터 | 이름 : a 값 : 5004 | 이름 : b 값 : 5005 |
기본형 데이터와 참조형 데이터의 차이는 '프로퍼티 영역'이 별도로 존재한다는 점인데, 위의 상황을 본다면 객체가 별도로 할애한 영역은 변수 영역인데, '데이터 영역'은 기존의 메모리 공간을 그대로 활용하고 있다. ( 데이터영역에 저장된 값은 불변 값)
그러나 변수에는 다른 값을 얼마든지 대입할 수 있고 이 부분 때문에 참조형 데이터는 불변하지 않는다라고 한다.
var obj1 = {
a : 1,
b : 'bbb',
};
obj1.a = 2;
주소 | ... | 1002 | 1003 | 1004 | ... |
---|---|---|---|---|---|
데이터 | 이름 : obj1 값 : 5001 |
주소 | 5001 | 5002 | 5003 | 5004 | 5005 | 5006 |
---|---|---|---|---|---|---|
데이터 | @7001 ~ ? | 1 | 'bbb' | 2 |
주소 | 7001 | 7002 | 7003 | 7004 | 7005 |
---|---|---|---|---|---|
데이터 | 이름 : a 값 : 5006 | 이름 : b 값 : 5005 |
기존에 할당된 obj1의 a 프로퍼티의 값을 숫자 2로 재 할당한 경우 데이터 영역에 숫자 2가 할당되어있는지 확인하는데, 만약 없으면 역시 새로운 빈 공간을 할당 받아 저장한다.
또한, 기존에 @7001로부터만 참조 받고 있었던 @5004는 현재 어떤 변수도 자신을 참조 하고 있지 않기 때문에 가비지 컬렉터(garbage collector)의 수거 대상이 된다.
이 가비지 컬렉터는 런타임 환경에 따라 특정 시점이나 메모리 사용량이 포화 상태에 임박할 때 마다 자동으로 수거 대상들을 수거하고 수거된 메모리는 다시 새로운 값을 할당할 수 있는 빈 공간이 된다.
var obj = {
x : 3,
arr : [ 3, 4, 5]
};
주소 | ... | 1002 | 1003 | 1004 | ... |
---|---|---|---|---|---|
데이터 | 이름 : obj 값 : 5001 |
주소 | 5001 | 5002 | 5003 | 5004 | 5005 |
---|---|---|---|---|---|
데이터 | @7001 ~ ? | 3 | @8001~ ? | 4 | 5 |
주소 | 7001 | 7002 | 7003 | 7004 | 7005 |
---|---|---|---|---|---|
데이터 | 이름 : x 값 : @5002 | 이름 : arr 값 : 5003 |
주소 | 8001 | 8002 | 8003 | 8004 | 8005 |
---|---|---|---|---|---|
데이터 | 이름 : 0 값 : @5002 | 이름 : 1 값 : @5004 | 이름 : 2 값 : @5005 |
위처럼 데이터가 할당된 경우 obj.arr[1]의 데이터 값을 검색하고자 하면?
메모리 검색 과정
1. 'obj'라는 식별자를 가진 주소를 찾는다 (@1003)
2. 값이 주소이므로 그 주소로 이동한다 (@5001)
3. 값이 주소이므로 그 주소로 이동한다 (@7001~?)
4. arr이라는 식별자를 가진 주소를 찾는다 (@7002)
5. 값이 주소이므로 그 주소로 이동한다 (@5003)
6. 값이 주소이므로 그 주소로 이동한다 (@8001~?)
7. 인덱스 1에 해당하는 주소를 찾는다 (@8002)
8. 값이 주소이므로 그 주소로 이동한다 (@5004)
9. 값이 숫자형 데이터이므로 숫자형 데이터 4를 반환한다.
var a = 10;
var b = a;
주소 | 1001 | 1002 | 1003 |
---|---|---|---|
데이터 | 이름 : a 값 : @5001 | 이름 : b 값 : @5001 |
주소 | 5001 | 5002 | 5003 |
---|---|---|---|
데이터 | 10 |
위의 상황을 봤을때 @1001, @1002 모두 @5001의 주솟값을 참조 하고있음을 알 수 있다.
즉, 복사하는 과정은 복사하는 대상과 피복사 대상 모두 같은 주소를 바라보게 한다.
var obj1 = { c: 10, d : 'ddd};
var obj2 = obj1;
주소 | 1001 | 1002 | 1003 |
---|---|---|---|
데이터 | 이름 : obj1 값 : @5001 | 이름 : obj2 값 : @5001 |
주소 | 5001 | 5002 | 5003 |
---|---|---|---|
데이터 | @7001~? | 10 | 'ddd' |
주소 | 7001 | 7002 | 7003 |
---|---|---|---|
데이터 | 이름 : c 값 : @5002 | 이름 : d 값 : @5003 |
참조형 데이터에서의 변수 복사하는 과정은 기본형 데이터와 같이 모두 같은 주소를 바라보게 하는 점이 동일하다. 하지만, 데이터 할당 과정에서 차이가 있기 때문에 변수 복사 이후 동작에 차이가 생긴다.
var a = 10;
var b = a;
b = 15;
주소 | 1001 | 1002 | 1003 |
---|---|---|---|
데이터 | 이름 : a 값 : @5001 | 이름 : b 값 : @5002 |
주소 | 5001 | 5002 | 5003 |
---|---|---|---|
데이터 | 10 | 15 |
기본형 데이터의 경우 기본형 데이터를 복사한 변수 b의 값을 바꿨더니 @1002가 참조하고있는 주소가 변경되었다.
즉, 변수 A와 B는 서로 다른 값을 바라본다. (a !== b)
var obj1 = { c: 10, d : 'ddd};
var obj2 = obj1;
obj2.c = 20;
주소 | 1001 | 1002 | 1003 |
---|---|---|---|
데이터 | 이름 : obj1 값 : @5001 | 이름 : obj2 값 : @5001 |
주소 | 5001 | 5002 | 5003 | 5004 |
---|---|---|---|---|
데이터 | @7001~? | 10 | 'ddd' | 20 |
주소 | 7001 | 7002 | 7003 |
---|---|---|---|
데이터 | 이름 : c 값 : @5004 | 이름 : d 값 : @5003 |
참조형 데이터를 복사한 변수의 프로퍼티 값 변경한 경우에는 해당 변수의 값이 변경되지 않고 여전히 같은 값을 가지고 있다. ( obj1 === obj2)
즉, obj2 내부 프로퍼티만 변경했어도 같은 주소를 참조하고 있는 obj1의 값도 같이 변경된다는 것이다. 이것이 기본형 데이터와 참조형 데이터의 가장 큰 차이점이다.
『코어 자바스크립트』 (정재남, 위키북스)