코어 자바스크립트를 읽으면서 공부한 내용을 저의 입맛에 맞춰 정리하였습니다. 혹시 이 글을 읽게 되시면 잘못된 내용이 있을 수 있으니 비판적인 시각으로 읽으시는 걸 추천드립니다.
자바스크립트의 데이터 타입
자바스크립트의 데이터 타입에는 크게 두 가지 기본형(Primitive) 참조형(Reference)이 있습니다.
일반적으로 기본형은 할당이나 연산 시 복제되고 참조형은 참조된다고 알려져 있습니다. 하지만, 엄밀히 말하면 두 데이터 타입 모두 데이터 주소를 참조하고 있고, 기본형은 주소 값을 바로 복제하지만, 참조형은 값이 담긴 주소 값들로 이루어진 묶음을 가리키는 주소 값을 복제합니다.
즉, 기본형은 주소 값을 바로 복제하기 때문에 불변성을 가지게 되고, 참조형은 보통 그렇지 못합니다.
결국 둘 데이터 타입에 차이는 불변성이라는 것인데 그렇다면 불변성은 무엇일까요?
불변성
자바스크립트의 변수 선언과 데이터 할당 과정을 통해 불변성을 이해해 보겠습니다.
1. 기본형 데이터 타입의 선언 및 할당, 변화
var a // 변수 a 선언
a = 'abc' // a에 데이터 할당
a = 'abcdef'
- 선언
- 첫 번째로 변수 영역에서 빈 공간(위 그림에서 @1003)을 확보합니다
- 확보한 공간의 식별자를 a로 지정합니다
- 할당
- 데이터 영역에서 'abc'란 값이 있는지 찾고, 없으므로 빈 공간에 'abc'를 저장합니다
- 변수 영역에서 a라는 식별자를 찾고, 그 값으로 앞서 데이터 영역에 'abc'를 저장한 주소를 대입한다.
- 변경
- 데이터 영역에서 'abcdef'란 값을 찾고, 없으므로 빈 공간(위 그림에서 @5005)에 'abcdef'를 저장합니다
- 변수 영역에서 a라는 식별자의 값을 'abcdef'를 가진 주소 @5005로 변경해 줍니다
위 과정을 통해 기본형 데이터 타입의 선언 및 할당, 그리고 변화까지 이루어집니다. 결국 a의 값이 'abc'에서 'abcdef'로 변경되었기 때문에 기본형 데이터는 불변하지 않는 것이 아닌가 라는 의문이 듭니다.
이때, 불변 값과 상수를 구분하여야 합니다. 불변성의 여부를 구분할 때 변경 가능성의 대상은 변수 영역의 값이 아닌, 데이터 영역의 메모리입니다.
위 예제에서 a의 값이 'abc'에서 'abcdef'로 변경될 때, @5004의 값 'abc'가 'abcdef'로 변경된 것이 아닌, @5005에 새로운 값 'abcdef'를 만들어 이 주소를 변수 a에 저장하였습니다. 즉 'abc'와 'abcdef'는 완전히 별개의 데이터고, 위와 같이, 이런 변경은 새로운 데이터를 새로 만드는 동작을 통해서만 이뤄집니다.
그리고 이것이 '불변성'입니다.
2. 참조형 데이터 타입의 선언 및 할당, 변화
var obj = {
x : 3,
arr : [3, 4, 5]
} // 선언 및 할당
obj.arr = 'str' // 변경
- 선언
- 변수 영역의 빈 공간을 확보한 후, 그 주소의 이름을 obj로 지정합니다
- 임의의 데이터 저장공간(위 그림에서 @5001)에 데이터를 저장하여야 하는데, 데이터가 여러 개의 값으로 이루어진 객체이기 때문에 별도의 변수 영역을 하나 더 만들고 그 변수들을 저장한 공간 (@7103~?)의 주소를 @5001에 저장합니다
- @7103에 이름 x를, @7104에 이름 arr을 지정합니다.
- 할당
- 데이터 영역에서 3을 찾습니다, 없을 경우 새로 만든 후 그 주소 값을 @7103에 저장합니다
- 데이터 영역에서 arr의 값을 찾아야 하지만, 여러 개의 값으로 이루어져 있기 때문에, 위 선언 2의 과정을 반복합니다
- 각각의 인덱스의 값을 데이터 영역에서 찾고, 그 데이터 영역의 주소를 값으로 가집니다.
- 변경
- 데이터 영역에서 'str'을 찾고, 그 주소 값을 @7104에 대입합니다.
- @5003을 참조하는 값이 없기 때문에 @5003은 가비지 컬렉터에 의해 수거 대상이 됩니다.
마지막으로 이 둘 데이터의 복사 과정을 보면서 불변성 차이를 확인해보겠습니다.
3. 변수 복사 비교
et a = 10;
let b = a;
let obj1 = { c: 10, d: 'ddd' };
let obj2 = obj1;
b = 15;
obj2.c = 20
기본형 객체는 값이 변할 때, 기존의 값을 변화하는 것이 아닌 데이터 영역에서 새로운 값을 만들고, 그 주소 값을 가지게 됩니다. 즉, 두 개의 변수 a와 b는 다른 주소를 바라보게 됐습니다. 하지만, 변수 obj1과 obj2는 변경 후에도 여전히 같은 객체를 바라보고 있습니다.
변화하는 과정에서 @5002의 주소 값을 새로 만드는 것이 아닌, @5002가 가리키고 있는, @7103의 값을 새로운 값으로 변경하기 때문입니다.
두 개의 obj1, obj2는 여전히 같은 @5002를 보고 있고, obj2.c를 20으로 바꾸었지만, obj1.c 역시 20이 됩니다.
4. 내가 이해한 내용
결국 기본형 데이터와 가변형 데이터는 둘 다 참조형 데이터지만, 참조형 데이터는 주소 값을 복사하는 과정이 한번 이루어지고, 참조형 데이터는 한 단계 더 거치게 된다는 차이가 있습니다. 이 과정에서 기본형 데이터는 값이 변화하지 않고, 새로운 데이터를 생성해야 하는 불변성이라는 특징을 가지게 되며, 참조형 데이터와 차이가 생기게 됐다고 이해했습니다..
.
'CS' 카테고리의 다른 글
[JS] this (feat : 코어 자바스크립트) (0) | 2022.12.15 |
---|---|
[JS] 실행컨텍스트 (feat : 코어 자바스크립트) (0) | 2022.12.14 |
[JS] undefined와 null (feat : 코어자바스크립트) (0) | 2022.12.13 |
[JS, React] ref, useRef (0) | 2022.08.25 |
[JS] array.reduce를 활용한 동기 호출 (0) | 2022.06.15 |