데이터 타입-2 (feat. 코어 자바스크립트)

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

🔥 불변값

변수(variable) VS 상수(constant)

바꿀수 있으면 변수, 바꿀수 없으면 상수
하지만 불변값상수는 같은 개념이 아니다.

변수와 상수를 구분 짓는 변경 가능성의 대상은 변수 영역 메모리 이다.
한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재 할당할수 있는지 여부 => 변수 or 상수

불변성 여부를 구분할 때의 변경 가능성의 대상은 데이터 영역 의 메모리이다

✔️ 기본형 데이터인 숫자, 문자열, boolean, null, undefined, Symbol은 모두 불변값이다.

결론

  • 문자열 값 또는 숫자 값도 다른 값으로 변경 할 수 없다.
  • 변경은 새로 만드는 동작을 통해 이루어진다.
  • 한 번 만들어진 값은 가비지 컬렉팅을 하지않는 한 영원히 변하지 않는다.

🔥 가변값

🌈 참조형 데이터의 할당

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

🌈 참조형 데이터 할당과정

  1. 변수 영역의 빈 공간(@1002)를 확보하고, 그 주소의 이름을 obj1로 지정합니다.
  2. 임의의 데이터 영역(공간)(@5001)에 데이터를 저장하려고 보니 여러 개의 프로퍼티로 이루어진 데이터 그룹! {a : 1, b : 'bbb}
  3. 이 그룹의 프로퍼티들을 저장하기 위해 별도의 변수 영역(@7103, @7104)을 마련하고, 그 영역의 주소를 @5001에 저장한다.
  4. @7103 및 @7104에 각각 a와 b라는 프로퍼티 이름을 지정합니다.
  5. 데이터 영역에서 숫자 1을 검색합니다. 검색 결과가 없으므로 @5003에 저장하고, 이 주소를 @7103에 저장한다. 문자열 "bbb"역시 마찬가지.

✔️ 기본형 데이터와의 차이는 '객체의 변수(프로퍼티) 영역'이 별도로 존재한다는 점이다.

🌈 참조형 데이터의 재할당

var obj1 = {
	a : 1,
  	b : 'bbb'
};
obj1.a = 2; // obj1의 a의 프로퍼티를 재 할당 해보자.

  1. 데이터 영역에서 숫자 2를 검색한다.
  2. 검색결과가 없으므로 데이터 영역의 빈 공간(@5005)을 만들고 2를 저장한다.
  3. 이 주소(@5005)를 @7103에 저장한다.
  4. 하지만 변수 obj1이 바라보고 있는 주소는 @5001로 변하지 않았다.
  5. 새로운 객체가 만들어진것이 아니라 기존 객체의 내부의 값만 바뀌었다.

🌈 참조형 데이터의 프로퍼티에 참조형 데이터를 할당

var obj1 = {
	x : 3,
  	arr : [3,4,5] //새로운 참조형 데이터 할당.
};

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

obj.arr[1]을 찾아가는 과정을 설명해보자!

  • 최상단 주소에서 타고 타고 들어간다.

가비지 컬렉션이 처음 나옴!

var obj1 = {
	x : 3,
  	arr : [3,4,5] 
};
obj1.arr = 'str'; // 새로운 문자열 할당 한다면?!
  1. 데이터 영역(@5006)에 문자열 'str'이 있는지 검사하고, 그 데이터 영역(@5006)주소를 기존 arr이 있던(@7104)에 저장합니다.
  2. 기존 데이터 영역(@5003)은 더이상 자신의 주소를 참조하는 변수가 하나도 없게 됩니다. 참조 카운트 "0"
  3. 어떤 데이터에 대해 자신의 주소를 참조하는 변수의 개수를 참조 카운트라고 합니다.
  4. 참조 카운트가 0인 메모리 주소는 가비지 컬렉터의 수거 대상이 됩니다.

가비지 컬렉터는 런타임 환경에 따라 특정 시점이나 메모리 사용량이 포화 상태에 임박할 때마다 자동으로 수거 대상들을 수거 합니다. 수거된 메모리는 다시 새로운 값을 할당 할 수 있는 빈 공간이 됩니다.

  1. (@5003)은 참조 카운트가 0이 됨에 따라 가비지 컬렉터 대상이 되고, 데이터 영역의 데이터인 @8104~@8106라는 값이 사라집니다.
  2. 이 과정에서 @8104~8106의 데이터들의 참조 카운트가 0이 되고, 가비지 컬렉터의 대상이 되어 함께 사라집니다.

🔥 변수 복사 비교

var a = 10;
var b = a; // 기본형 복사

var obj1 = {c : 10, d : 'ddd'};
var obj2 = obj1; // 참조형 복사

✅ 기본형 데이터 복사

  1. 변수 a 선언 및 할당 (생략)
  2. 변수 영역의 빈 공간 (@1002)를 확보하고, 식별자를 b로 지정한다.
  3. 변수 영역의 값의 주소 (@5001)을 좀 전에 확보해둔 (@1002)에 값으로 대입합니다.

✅ 참조형 데이터 복사 과정

1. 참조형 데이터 저장
1. 변수 영역의 빈 공간 (@1003)을 확보하고 식별자를 obj1로 지정합니다.
2. 데이터 영역의 빈 공간 (@5002)을 확보하고 데이터 그룹이 담겨야 하기때문에 (@5002)의 변수 영역을 따로 생성한다.
3. (@5002)의 변수영역의 주소(@7103, @7104)을 확보하여 데이터 영역의 주소(@5002)에 (@7103,@7104)를 저장합니다.
4. (@7103)에는 식별자 c를, (@7104)에는 식별자 d를 입력한 다음, c에 대입할 값 10을 데이터 영역에서 검사합니다.
5. 데이터 영역(@5001)에 이미 10이 저장되있으므로 이 주소(@5001)을 (@7103)에 연결합니다.
6. d에 대입할 문자열 "ddd"가 데이터 영역에 없으므로, (@5003)에 빈 공간을 만들어 "ddd"를 저장한후 (@7104)영역에 연결합니다.

2. 참조형 데이터 복사
1. 변수 영역의 빈 공간 (@1004)를 확보하고 식별자를 obj2로 지정합니다.
2. 이제 식별자 obj1을 검색해(@1003) 그 해당하는 값인 (@5002)를 들고 (@1004)주소에 대입합니다.

변수를 복사하는 과정은 기본형 데이터참조형 데이터 모두 같은 주소를 바라보게 되는 점이 동일합니다.

✅ 변수 복사 이후 값 변경 결과

var a = 10;
var b = a; // 기본형 복사

var obj1 = {c : 10, d : 'ddd'};
var obj2 = obj1; // 참조형 복사

b = 15;
obj2.c = 20;

결론 : 변수 a와 b는 서로 다른 주소(@5001), (@5004)를 바라보게 되었지만,
변수 obj1과 obj2는 여전히 같은 객체(@5002)를 바라보고 있다.

a !== b
obj1 === obj2

💡 추가로 자바스크립트의 어떤 데이터 타입이던 변수에 할당하기 위해서는 주소값을 복사해야하기 때문에, 모든 데이터 타입은 참조형 데이터일 수 밖에 없다. (기본형도 결국 주솟값을 참조한다!)

💡 기본형 데이터와 참조형 데이터의 가장 큰 차이점

  • 기본형 데이터는 주소 값을 복사하는 과정이 한 번만 이루어지고, 참조형은 한 단계를 더 거치게 된다.
  • 참조형 데이터가 '가변값'이라고 설명할 때의 '가변'은 참조형 데이터 자체를 변경할 경우가 아니라 그 내부 프로퍼티를 변경할 때만 성립한다.

✅ 객체 자체를 변경

var a = 10;
var b = a; // 기본형 복사

var obj1 = {c : 10, d : 'ddd'};
var obj2 = obj1; // 참조형 복사

b = 15;
obj2 = { c : 20, d: 'ddd' }; // 객체 자체를 변경

이렇게 내부 프로퍼티가 아닌 객체 자체를 변경하게 되면 메모리 영역의 새로운 객체가 저장되고 그 새로운 주소를 변수 obj2에 저장한다.

좋은 웹페이지 즐겨찾기