자바스크립트 타입과 그 차이가 발생하는 원인에 대해서 파악을 해야한다.
해당 글은 코어 자바스크립트 강의를 요약하면서 공부하였다.
자바스크립트는 원시타입 (Primitive Type)과 참조 타입(Reference Type)이라는 두가지 타입의 자료형을 제공한다.
- 원시타입 (Primitive Type)은 immutable(불변성) 이다.
새롭게 메모리 주소가 만들어 지는 것이 아니다.
한번 만들어진 메모리에 저장된 값이 불변한다.
변하지 않는 성질로 즉, 생긴게 다르면 결국 다른 것
- string
- number
- boolean
- undefined
- null
- Symbol(es6)
- 참조 타입(Reference Type)
- Object
- Array
- Function
- RegExp
- Set/ WeakSet
- Map/ WeakMap
- 메모리의 동작 방식 (보류)
스택, 힙은 실행 컨텍스트 부분에 다시 정리 해 두기로 하고
현재는 데이터 타입에 흐름만 간단하게 정리해보자
- stack memory: 변수/ 기본형 데이터/ 정적 할당
- heap memory: 참조형 데이터/ 동적 할당
🔷 [기본적인 데이터 할당 순서]
메모리에 각각 주소가 부여된다.
변수 a의 메모리 안에 데이터가 담길 공간을 미리 확보한다.
a의 값인 'abc' 도 비어있는 다른 메모리 공간에 저장이 되고 해당 주소가 변수 a가 가리키는 주소 공간을 이동 한다.
var a
a = 'abc'
주소 | 1002 | 1003 | ... |
데이터 | 이름: a 값: @5004 |
주소 | 5003 | 5004 | ... |
데이터 | 'abc' |
주소 | 1002 | 1003 | ... |
데이터 | 이름: a 값: @5005 |
주소 | 5003 | 5004 | 5005 |
데이터 | 'abc' | 'abcdef' |
🔷 [참조형 데이터]
기본형 데이터의 할당과 다르게 참조형 데이터는 할당 전에 한 단계를 더 거치게 된다.
var obj = {
a: 1,
b: 'bbb'
}
주소 | 1002 | 1003 | ... |
데이터 | 이름: obj 값: @5002 |
주소 | 5002 | 5003 | 5004 |
데이터 | @7103 ~? | 1 | 'bbb' |
▼ 한 단계 더 걸쳐서
주소 | 7103 | 7104 | ... |
데이터 | 이름: a 값: @5003 |
이름: b 값: @5004 |
주소 | 1002 | 1003 | ... |
데이터 | 이름: obj 값: @5002 |
주소 | 5002 | 5003 | 5004 | 5005 |
데이터 | @7103 ~? | 1 | 'bbb' | 2 |
주소 | 7103 | 7104 | ... |
데이터 | 이름: a 값: @5005 |
이름: b 값: @5004 |
var obj = {
x: 3,
arr: [3, 4]
}
주소 | 1002 | 1003 | ... |
데이터 | 이름: obj 값: @5002 |
주소 | 5002 | 5003 | 5004 | 5005 |
데이터 | @7103 ~? | 3 | @8104 ~ ? | 4 |
주소 | 7103 | 7104 | ... |
데이터 | 이름: x 값: @5003 |
이름: arr 값: @5004 |
주소 | 8104 | 8105 | ... |
데이터 | 이름: 0 값: @5003 |
이름: 1 값: @5005 |
@8104 ~ 의 메모리들은 arr의 배열 값을 확보해놨다.
@8104는 @5003 주소를 바라보며 해당 값은 배열의 첫번째 이다.
@8105도 @5005를 바라보고 있고 배열의 2번째 값이다.
🔸가비지 컬렉팅 수집
[참조하고 있던 데이터 가 필요 없어졌을 때]
주소 | 5002 | 5003 | 5004 | 5005 | 5006 |
데이터 | @7103 ~? | 3 | @8104 ~ ? | 4 | 'str' |
5006번의 주소에 str의 값의 데이터가 생겼고
obj.arr 주소 7104은 값의 주소를 @ 5006으로 바꿀 것이다.
그렇다면 참조하고 있는 대상이 아무것도 없을 때? : 참조 카운트가 0 인 상태일 때
이렇게 된 메모리들은 모두 가비지 컬렉터에 수집되게 된다.
또한 가비지 컬렉터에 들어간 메모리를 참조하고 있는 대상들도 다 함께 사라지게 된다.
arr 값의 주소 @5004는 참조하는 대상이 0으로 변해버렸다.
@5004의 참조하고 있는 대상인 @8104 ~ 의 메모리 또한 필요가 없어졌기에 연쇄적으로 참조 카운트가 0으로 바뀌게 된다.
정리를 하자면!
🔹[기본형 데이터]
불변값이다. 같은 값이 오직 하나만 존재한다.
주소 | 1002 | 1003 | ... |
데이터 | 이름: a 값: @5003 |
이름: b 값: @5004 |
주소 | 5003 | 5004 | ... |
데이터 | 10 | 15 |
🔹[참조형 데이터]
주소 | 1004 | 1005 | ... |
데이터 | 이름: obj1 값: @5003 |
이름: obj2 값: @5003 |
주소 | 5003 | 5004 | 5005 |
데이터 | @7103~ | 15 | 20 |
주소 | 7103 | 7104 | ... |
데이터 | 이름:c 값: @5003 |
이름:d 값: @5004 |
▼ 바라보는 값의 주소값이 바뀜
주소 | 7103 | 7104 | ... |
데이터 | 이름:c 값: @5005 |
이름:d 값: @5004 |
여기서 문제점은, 여전히 1004, 1005 주소는 같은 값을 가리킨다.
같은 곳을 바라보고 있기에 obj.c 인 원본 객체의 값도 같이 바뀌게 되었다.
var obj1 = { c: 10, d: 'ddd'}
var obj2 = obj1
obj2.c = 20
console.log('obj1: ', obj1);
console.log('obj2: ', obj2);
//obj1: { c: 20, d: 'ddd' }
//obj2: { c: 20, d: 'ddd' }
🔸참조형 데이터, 객체를 복사 -> 복사한 객체의 값을 바꿨는데 원본객체 값도 같이 바뀌게 되는 문제점 발생!!
참조형 데이터의 데이터 할당은
- 가변형이기에 생김새가 똑같더라도 같은 데이터가 아닐 수 있다.
- 한쪽을 수정하면 다른 쪽도 수정된다.
- 할당 연산자로 다른 연산자로 할당 할 때 의도치않게 데이터가 변경될 수 있다.
- 구분해서 관리하고 싶을 때는 복사의 개념을 활용해야한다.
'programming language > Javascript' 카테고리의 다른 글
callback, promise, async/await (0) | 2022.11.03 |
---|---|
변수에 대하여 (0) | 2022.10.13 |
얕은복사 깊은복사 개념 (0) | 2022.09.02 |
Symbol (0) | 2022.09.01 |
모던 자바스크립트 Deep Dive 훑기 (1) | 2022.08.30 |
댓글