데이터 할당 흐름

준호·2020년 10월 3일
0
post-thumbnail

불변값 !== 상수

바꿀수 있다면 변수, 바꿀수 없다면 상수

변수와 상수를 구분짓는것은 변수영역의 메모리이다.
불변성 여부를 구분짓는것은 데이터 영역의 메모리이다.

불변값

원시 값은 모두 불변값이다. (Number, String, Boolean, Null, undefined, Bigint, Symbol)

불변값의 변경은 새로 만드는 동작을 통해서만 가능하다.
한번 만들어진 값은 가비지 컬렉팅을 당하지 않는 한 영원히 변하지 않는다.

가변값

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

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

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

참조형 데이터의 프로퍼티 재할당

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

obj1의 a의 값을 변경했을때 데이터는 이런식으로 변경된다.

중첩된 참조형 데이터의 프로퍼티 할당

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

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

만약 obj.arr[1]를 검색한다면 겪는 메모리 검색 과정

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

추가로 재할당 명령을 내린다면?

obj.arr = 'str';

5006에 문자열 str를 저장하고 그 주소를 7104에 저장할것이다.
이제 7014가 가리키던 5003은 더이상 자신의 주소를 참조하는 변수가 하나도 없게된다
현재 5003의 참조카운트는 직전까지 1이었다가 현재 0이 되었다.
수거된 메모리는 새로운 값을 할당 할 수 있는 빈 공간이 된다.
5003이 담고있던 8104~8106 영역 또한 다른곳에서 가리키지 않으니 참조카운트가 0이 되고 가비지 컬렉터의 대상이 된다.

[참조 카운트]: 어떤 데이터에 대해 자신의 주소를 참조하는 변수의 갯수, 0일경우 가비지컬렉터의 수거 대상이 된다.
[가비지 컬렉터]: 프로그램이 동적으로 할당했던 메모리 영역중 필요없게된 영역을 해제하는것, 특정 시점이나 메모리 사용량이 포화 상태에 임박할 때 마다 자동으로 수거 대상들을 수거한다.

변수 복사 비교

var a = 10;
var b = a;
var obj1 = { c: 10, d: 'ddd'};
var obj2 = obj1;

기본형 데이터 할당

  1. 변수 영역의 빈 공간 1001을 확보하고 식별자를 a로 지정
  2. 숫자 10을 데이터영역에서 검색하고, 없으므로 빈공간 @5001에 저장
  3. 5001의 주소를 1001에 저장
  4. 변수 영역의 빈 공간 1002를 확보하고 식별자를 b로 지정
  5. 식별자 a를 검색해 그 값을 찾아온다, 1001에 저장된 값인 5001을 들고 1002에 대입한다

참조형 데이터 할당

  1. 변수 영역의 빈 공간 1003을 확보하고 식별자를 obj1로 지정
  2. 데이터 영역의 빈 공간 5002를 확보하고 데이터 그룹이 담겨야 하기에 변수영여 7103 ~ ? 를 확보해 그 주소를 저장
  3. 7103에는 식별자 c를 7014에는 식별자 d를 입력한 다음 c에 대입할 값 10을 데이터 영역에서 검색
  4. 5001에 이미 10이 있으므로 이 주소를 7103에 연결하고 문자열데이터인 ddd는 데이터 영역의 빈 공간(5003)에 새로 만들어 7104에 저장
  5. 변수 영역의 빈 공간 1004를 확보하고 식별자를 obj2로 지정
  6. obj1 식별자를 검색해 그 값인 5002를 들고 1004에 값으로 대입

변수 복사 이후 값 변경 결과 비교

var a = 10;
var b = a;
bar obj1 = { c: 10, d: 'ddd'}
var obj2 = obj1;

b = 15;
obj2.c = 20;

  1. 1번줄부터 4번줄까지는 앞의 예제와 같다.
  2. 6번째 줄에서는 데이터 영역에 아직 15가 없으므로 새로운 공간 5004에 15를 저장하고 변수영역에서 식별자가 b인 주소를 찾아 자신의 주소를 대입한다.
  3. 7번째 줄에서는 데이터 영역에 아직 20이 없으므로 새로운 공간 5005에 저장하고, 변수 영역에서 obj2를 찾고, 그의 값인 5002가 가리키는 변수영역에서 다시 c를 찾아 자신의 주소를 대입한다.
var a = 10;
var b = a;
bar obj1 = { c: 10, d: 'ddd'}
var obj2 = obj1;

b = 15;
obj2 = { c: 20, d: 'ddd'};

obj2에 새로운 객체를 할당했으므로 새로운 객체의 변수 영역을 다시 지정한다, 결과적으로 객체의 대한 변경임에도 값이 달라진다.

참조형 데이터가 가변값 이라고 설명할 때의 '가변'은 참조형 데이터 자체를 변경 할 경우가 아니라 그 내부의 프로퍼티를 변경 할 때만 성립한다.

profile
빠르게 발전중인 프론트엔드 개발자

0개의 댓글