본문 바로가기

WEB/HTML CSS JS

[JS] 데이터 할당의 동작 원리와 불변값 vs 가변값

코어 자바스크립트 1장을 읽고 정리한 내용 (1)

 

1. 데이터 타입의 종류
2. 데이터 할당의 동작 원리
    2-1. 기본형의 데이터 할당

    2-2. 참조형의 데이터 할당
3. 불변값과 가변값
    3-1. 기본형과 참조형 데이터에서 할당된 값을 변경할 때
4. 얕은 복사와 깊은 복사
    4-1. 불변 객체
    4-2. 복사한 데이터를 변경할 때 원본 데이터의 변경 여부
    4-3. 불변객체를 만드는 방법

 

1. 데이터 타입의 종류

  • Primitive Type (기본형)
  • Reference Type (참조형)

Symbol, Map, WeakMap, Set, WeakSet 은 ES6 에서 추가되었다.

둘의 차이점

데이터를 할당하거나 연산할 때,

- 기본형은 값이 담긴 주소값을 바로 복제하고

- 참조형은 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제한다.

- 둘 다 주소의 복사가 이루어지지만, 참조형의 경우 내부의 값에 대해서 한 단계의 복사가 더 있다는 점이 다르다.

 


 

기본형은 불변성(immutability)을 가진다고 알려져 있다. 데이터가 메모리에 어떻게 할당되는지 먼저 알아보고, 할당된 데이터를 변경할 때 어떻게 변경되는지 알아보면 불변성의 개념을 이해할 수 있다.

 

 

2. 데이터 할당의 동작 원리

2 - 1. 기본형의 데이터 할당

 

아래와 같이 간단하게 변수를 선언하고 문자열 데이터를 할당할 때, 다음의 과정을 거친다.

var a;
a = 'abc';

//또는
var a = 'abc';

(변수 영역, 데이터 영역이 따로 정의되어 있는 건 아니지만, 책에서는 이해의 편의를 위해 나누어져있다고 가정하고 설명한다.) 

1) 변수 영역에 비어있는 공간을 확보해 a라는 이름을 붙인다.

2) a 라는 공간에 바로 문자열 'abc'를 저장하는게 아니라
3) 별도의 메모리 공간(데이터 영역)에 'abc'를 저장하고 저장된 공간의 주소값(@5004)을 변수 영역의 a에 저장한다.

 

이런 과정을 거쳐 저장을 하는 이유는 메모리를 더 효율적으로 관리하기 위함이다. 

다음 두 가지 경우를 생각해보면 왜 이 방법이 더 효율적인지 알 수 있다.

  • 데이터 변환을 해야할 때

    ex) 'abc' 를 'abcdef' 로 변환하는 경우
    만약 a 변수를 위해 미리 확보해 둔 메모리 공간이 충분하지 않다면 메모리 재할당을 해야하는데
    a가 메모리상에서 중간에 위치한다면, a 뒤의 데이터를 전부 뒤로 밀고 재할당을 해야하는 번거로움과 비효율이 있음.

  • 여러개의 변수에 똑같은 데이터를 할당할 때

    ex) 500개의 변수에 전부 숫자 5를 할당하는 경우
    500개의 변수에 8byte 크기의 숫자형 데이터를 일일이 저장하면 500 * 8 = 4000 byte 를 사용해야하는데
    숫자 5를 별도의 공간에 한번만 저장하고 500개의 변수가 이를 참조하면, 훨씬 적은 공간으로 데이터를 할당할 수 있다.

 

2 - 2. 참조형의 데이터 할당

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

1) 변수 영역에 비어있는 공간 @1003을 확보해 식별자를 obj1로 지정.

2) 데이터영역 @5001에 그룹이 담겨야 하므로 별도의 변수영역 @7103~ 을 확보하고 그 주소를 저장한다.
3) @7103 에는 식별자 a를, @7104 에는 식별자 b를 담고 데이터 영역(@5003, @5004)에 해당 값들을 저장하고 연결해준다. 

 

3. 불변값과 가변값

불변값

위에서 기본형 데이터는 불변성을 가지고 있다고 했는데, 불변성을 이야기할 때 "변경가능성"의 대상은 데이터영역 메모리이다.

 

※ 상수(constant) 와 불변값을 같은 개념으로 오해하기 쉬운데, "변경가능성"의 대상이 무엇이냐에 따라 구분할 수 있다.
- 상수의 변경 가능성의 대상은 변수 영역 메모리. (한번 할당이 이루어진 변수에 다른 데이터를 재할당할 수 없다.)
- 불변성의 변경 가능성의 대상은 데이터 영역 메모리. 

 

기본형 데이터를 재할당할 때 메모리에서 어떤 일이 일어나는지 보고 불변성의 개념을 이해해보자.

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

var b = 5;
b = 7;

위와 같이 변수에 저장된 값을 변경할 때, @5004의 'abc' 가 'abcdef' 로 바뀌는게 아니라 새로운 영역에 'abcdef' 를 만들어 그 주소를 변수 a 에 저장한다. 숫자 데이터도 마찬가지. 

이렇게 데이터의 변경이 새로 만드는 동작을 통해서만 이루어질 수 있는 것이 불변값의 특징이다.

 

가변값

참조형 데이터에서 내부의 프로퍼티 재할당이 어떻게 이루어지는지 보면 참조형 데이터는 왜 가변값인지 알 수 있다.

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

obj1.a = 2;

obj1은 여전히 같은 객체를 가리키고(@5001) 있고, 내부 객체의 값이 @5003 에서 @5005 로 변경되었다!  

 

참고로 참조형 데이터가 가변값이라는 것은, 객체 내부의 프로퍼티를 변경할 때만 성립한다.

 

아래 코드에서처럼 객체 자체를 변경하는 경우에는 기본형 데이터에서처럼 obj1 이 새로운 객체를 가리키게 되기 때문에 가변성에 해당하지 않는다.

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

obj1 = { c: 20, d: 'ddd' };

- 참조형 데이터에서 객체 내부 프로퍼티를 변경 => 가변
- 참조형 데이터에서 객체 자체를 변경 => 불변

 

내용이 길어져서 얕은 복사와 깊은 복사는 글을 새로 파야할 것 같다.