자바스크립트 데이터 타입(2)

배기호 Notebook·2023년 7월 11일
0

JavaScript

목록 보기
2/13

기본형 데이터와 참조형 데이터

불변값

변수와 상수를 구분하는 성질은 '변경 가능성'이다.

불변값과 상수는 같은 개념인가?

변수와 상수를 구분 짓는 변경 가능성의 대상은 변수 영역 메모리이다.

한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지 여부가 관건이다.
반면 불변성 여부를 구분할 때 변경 가능성의 대상은 데이터 영역 메모리이다.

숫자, 문자열, boolean, null, undefined, Symbol 모두 불변값이다.
다음의 예로 불변성의 개념을 알아보자.

var a = 'abc';
a = a + 'def';

var b = 5;
var c = 5;
b = 7;

변수 a에 문자열 'abc'를 할당했다가 뒤에 'def'를 추가하면 기존의 'abc,가 'abcdef'로 바뀌는 것이 아니라 새로운 문자열 'abcdef'를 만들어 그 주소를 변수 a에 저장한다.
즉, 'abc' 와 'abcdef'는 완전 별개의 데이터이다.

변수 b에 숫자 5를 할당한다. 이때 컴퓨터는 데이터 영역에서 5를 찾고, 없으면 그제서야 데이터 공간을 하나 만들어 저장한다. 그 주소를 b에 저장한다.
이후 다시 c에 같은 수 5를 할당하려할 때
컴퓨터는 데이터 영역의 5를 찾고, 그 주소를 재활용한다.

이후 b의 값을 7로 바꾸고자 할때,
기존에 저장된 5 자체를 7로 바꾸는것이 아니라 기존에 저장된 7을 찾고, 없으면 새로 만들어 b에 저장한다.

결국 5와 7은 모두 다른값으로 변경할 수 없는 것이다.

이처럼 문자열 값도 한 번 만든 값을 바꿀 수 없고, 숫자도 마찬가지이다.
변경은 새로 만드는 동작을 통해 이루어진다. 이것이 불변값의 성질이다.

가변값

기본형 데이터는 모두 불변값이다. 그렇다면 참조형 데이터는 모두 가변값일까?

기본적인 성질은 가변값인 경우가 많지만 설정에 따라 변경 불가능한 경우도 있고, 아예 불변값으로 활용하는 경우도 있다.


참조형 데이터의 할당

var obj1 = {
	a: 1,
	b: 'bbb'
};

  1. 컴퓨터는 변수 영역의 빈 공간(@1002)을 확보하고, 그 주소 이름을 kbj1로 지정한다.
  2. 임의의 데이터 저장 공간(@5001)에 데이터를 저장하려고 보니 여러 개의 프로퍼티로 이뤄진 데이터 그룹이다. 이 그룹 내부의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고, 그 영역의 주조(@7103 ~ ?)를 @5001에 저장한다.
  3. @7103 및 @7104에 각각 a와 b라는 프로퍼티 이름을 지정한다.
  4. 데이터 영역에서 숫자 1을 검색한다. 검색 결과가 없으므로 임의로 @5003에 저장하고, 이 주소를 @7013에 저장한다. 문자열 'bbb'역시 임의로 @5004에 저장하고, 이 주소를 @7104에 저장한다.

기본형 데이터와의 차이는 '객체의 변수(프로퍼티) 영역'이 별도로 존재한다는 점이다.
객체가 별도로 할애한 영역은 변수 영역일 뿐 '데이터 영역'은 기존의 메모리 공간을 그대로 활용한다.
데이터 영역에 저장된 값은 모두 불변값이다. 그러나 변수에는 다른 값을 얼마든지 대입할 수 있다.
이 부분이 참조형 데이터는 불변하지 않다라고 하는 이유이다.


프로퍼티 재할당

var = obj1 = {
	a: 1,
	b: 'bbb'
};
obj1.a =2;

obj1의 a 프로퍼티에 숫자 2를 할당하려 한다.
먼저 데이터 영역에서 숫잘 2를 검색한다. 겸색 결과가 없으므로 빈 공간인 @5005에 저장하고, 이 주소를 @7103에 저장한다.
변수 obj1이 가리키는 주소는 @5001로 변하지 않는다.
즉, 새로운 객체가 만들어진 것이 아니라 기존의 객체 내부의 값만 바뀐것이다.


참조형 데이터의 프로퍼티에 다시 참조형 데이터를 할당하는 경우
(중첩 객체)

var obj = {
	x: 3,
	arr: [3, 4, 5]
};

  1. 컴퓨터는 변수영역의 빈 공간(@1002)을 확보하고, 그 주소 이름을 obj로 지정한다.
  2. 임의의 데이터 저장공간(@5001)에 데이터를 저장하려는데, 이 데이터는 여러 개의 변수와 값들을 모아놓은 그룹(객체)이다. 이 그룹의 각 변수들을 저장하기 위해 별도의 변수 영역(@7103 ~ ?)을 마련하고, 그 영역의 주소를 저장한다.
  3. @7013에 이름 x, @7104에 이름 arr 지정
  4. 데이터 영역에서 숫자 3을 검색하고, 없으므로 @5002에 저장하고, 이 주소를 저장한다.
  5. @7014에 저장할 값은 배열로서 역시 데이터 그룹이다. 이 그룹 내부의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고(@8104 ~ ?) 그 여역의 주소 정보를 @5003에 저장한다.
  6. 배열의 요소가 총 3개 이므로 3개의 변수 공간을 확보하고 각각 인덱스를 부여한다. (0, 1, 2)
  7. 데이터 영역에서 숫자 3을 검색해서(@5002) 그 주소를 @8014에 저장한다.
  8. 데이터 영역에 숫자 4가 없으므로 @5004에 저장하고, 이 주소를 @8105에 저장한다.
  9. 데이터 여역에 숫자 5가 없으므로 @5005에 저장하고, 이 주소를 @8106에 저장한다.

이후 obj.arr[1]을 검색하고자 하면 메모리에서는

  1. obj 검색 1: obj라는 식별자를 가진 주소를 찾는다.(@1002)
  2. obj 검색 2: 값이 주소이므로 그 주소로 이동(@5001)
  3. obj 검색 3: 값이 주소이므로 그 주소로 이동(@7103 ~ ?)
  4. obj.arr 검색 1: arr이라는 식별자를 가진 주소를 찾는다.(@7104)
  5. obj.arr 검색 2: 값이 주소이므로 그 주소로 이동(@5003)
  6. obj.arr 검색 3: 값이 주소이므로 그 주소로 이동(@8014 ~ ?)
  7. obj.arr[1] 검색 1: 인덱스 1에 해당하는 주소를 찾는다.(@8105)
  8. obj.arr[1] 검색 2: 값이 주소이므로 그 주소로 이동(@5004)
  9. obj.arr[1] 검색 3: 값이 숫자형 데이터이므로 4를 반환.

위 상태에서 다음과 같이 재할당 명령을 내리는 경우

obj.arr = 'str';

@5006에 문자열 'str'을 저장하고, 그 주소를 @7104에 저장한다.
그렇다면 @5003은 더이상 자신의 주소를 참조하는 변수가 하나도 없게 된다.
어떤 데이터에 대해 자신의 주소를 참조하는 변수의 개수를 참조 카운트라고 한다.
@5003의 참조 카운트는 이 시점에서 0이 되는 것이다.

참조 카운트가 0인 메모리 주소는 가비지 컬렉터의 수거 대상이 된다.
수거된 메모리는 다시 새로운 값을 할당할 수 있는 빈 공간이 된다.

참조 : 코어 자바스크립트

0개의 댓글