Data-type | 데이터 타입

코어 자바스크립트를 읽고 정리한 글입니다.

데이터 타입

데이터 타입의 종류

자바스크립트의 데이터 타입은 두 가지입니다.

  1. 기본형

    1. 숫자 number
    2. 문자열 string
    3. 불리언 boolean
    4. null
    5. undefined
    6. Symbol
  2. 참조형

    1. 객체 object
    2. 배열 Array
    3. 함수 Function
    4. 날짜 Date
    5. 정규표현식 RegExp
    6. Map, WeakMap, Set, WeakSet

기본형과 참조형의 차이점은 기본형은 값이 담긴 주소값을 복제하지만 참조형은 값이 담긴 주소값들의 묶음을 복제합니다.

기본형은 불변성을 띕니다.

데이터 타입에 관한 배경 지식

메모리와 데이터

컴퓨터의 모든 데이터는 0과 1로 이루어져 있습니다.

0과 1로 표현할수 있는 하나의 메모리 크기를 비트라고 하며 각 비트는 고유한 식별자를 통해 위치를 확인할 수 있습니다.

하지만 비트단위로 검색을 하면 매우 비효율적이라서 8비트를 묶은 바이트 단위로 검색을 합니다.

모든 데이터는 바이트 단위의 식별자, 메모리 주소값을 통해 서로 구분하고 연결할 수 있습니다.

식별자와 변수

변수는 변할수 있는 수 이며 컴퓨터 용어로는 변할수 있는 데이터를 의미합니다.

식별자는 어떤 데이터를 식별하는데 사용하는 이름이며 변수명이라고도 합니다.

변수 선언과 데이터 할당

변수 선언

var a;

위의 상황을 말로 풀면 변할수 있는 데이터를 만들고 데이터의 식별자는 a로 한다 입니다.

변수는 변경 가능한 데이터가 담길 수 있는 공간 또는 그릇이라고 도 할 수 있습니다.

위의 명령을 컴퓨터가 받으면 컴퓨터는 메모리에서 비어있는 공간 하나를 확보합니다.

주소100210031004
데이터이름: a 값:

그 공간의 이름(식별자)을 a로 지정합니다.

여기까지가 변수 선언 과정입니다.

사용자가 a에 접근하고자 하면 컴퓨터는 메모리에서 a라는 이름을 가진 주소를 검색해 해당 공간에 담긴 데이터를 반환합니다.

데이터 할당

var a;
a = "abc";
var a = "abc";

선언과 할당을 나누어서 하던 같이 하던 자바스크립트 엔진은 같은 동작을 수행합니다.

메모리에서 비어있는 공간을 확보한후 공간의 이름(식별자)을 a라고 합니다.

그리고 데이터를 저장하기 위해 별도의 메모리 공간을 확보해서 문자열 "abc"를 저장하고 그 주소를 변수 영역에 저장합니다.

변수 영역

주소100210031004
데이터이름: a 값: @5003

데이터 영역

주소500250035004
데이터"abc"
  1. 변수 영역에 빈 공간(@1003)을 확보한다

  2. 확보한 공간의 식별자를 a로 지정한다.

  3. 데이터 영역의 빈 공간(@5003)에 문자열 "abc"를 저장한다.

  4. 변수 영역에서 a라는 식별자를 검색한다.(@1003)

  5. 문자열의 주소(@5003)을 @1003의 공간에 대입한다.

변수 영역에 값을 직접 대입하지 않고 한 단계를 더 거치는 이유는 데이터 변환을 자유롭게 할 수 있고 동시에 메모리를 효율적으로 관리하기 위함이다.

미리 확보된 공간에서만 데이터를 변환 할 수 있다면 변환한 데이터를 저장하기 위해서는 확보된 공간을 변환된 데이터의 크기에 맞게 늘리는 작업이 선행이 되어야 한다.

해당 공간이 중간에 있다면 해당 공간 뒤에 저장된 데이터들을 전부 뒤로 옮기고 이동시킨 주소를 각 식별자에 다시 연결하는 작업을 해야 합니다.

결국 효율적으로 문자열 데이터 변환을 처리하려면 데이터를 별도의 공간에 나누어 저장하는 것이 최적입니다.

문자열 'abc'의 마짐가에 'def'를 추가하려면 컴퓨터는 'abc'가 저장된 공간에 'abcdef'를 할당하는 것이 아닌 'abcdef'라는 문자열을 새로 만들어 별도의 공간에 저장하고 그 주소를 변수 공간에 연결합니다.

기존 문자열에 어떤 변환을 가하든 상관없이 무조건 새로 만들어 별도의 공간에 저장합니다.

다른 예로 500개의 변수를 생성해서 숫자 5를 할당한다고 가정하면 각 변수를 별개로 인식하려면 500개의 변수 공간을 확보해야 합니다.

그리고 각 변수 공간을 5로 할당하려면 숫자형이므로 8바이트가 필요합니다.

고로 총 4000(500 * 8)바이트가 필요합니다.

하지만 그 대신 5를 별도의 공간에 한번만 저장하고 해당 주소를 입력한다면 주소 공간의 크기가 2바이트라고 하면 1008(500 * 2 + 8)바이트만 사용하게 됩니다.

변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아집니다.

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

불변값

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

바꿀 수 있으면 변수, 없으면 상수입니다.

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

한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지 여부가 관건입니다.

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

문자열 값도 한 번 만들면 값을 바꿀수 없고 숫자 값도 다른 값으로 변경할수 었습니다. 변경은 새로 만드는 동작으로 통해 이루어집니다.

이것이 불변값의 성질입니다.

가변값

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

변수 영역

주소100210031004
데이터이름: obj1 값: @5001

데이터 영역

주소5001500250035004
데이터@7103 ~1"bbb"

객체 @5001의 변수 영역

주소7103710471057106
데이터이름: a 값: @5003이름: b 값: @5004
  1. 변수 영역의 빈 공간(@1002)를 확보하고 그 주소의 이름을 obj1으로 지정한다.

  2. 임의의 데이터 공간(@5001)에 데이터를 저장하려고 보니 여러 개의 프로퍼티로 이루어진 데이터 그룹이다. 이 그룹 내부의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고 그 영역의 주소(@7103 ~)를 @5001에 저장합니다.

  3. @7103및 @7104에 각각 a와 b라는 프로퍼티 이름을 지정합니다.

  4. 데이터 영역에서 숫자 1을 검색하고 없으면 @5003에 저장하고 이 주소를 @7003에 저장합니다. 문자열 또한 같습니다.

기본형과의 차이는 객체의 변수 영역이 별도로 존재한다는 점입니다.

데이터의 영역에 저장된 값은 모두 불변값입니다. 그러나 변수에는 다른 값을 얼마든지 대입할 수 있습니다. 그렇기에 참조형은 불변하지 않습니다.

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

obj1의 a 프로퍼티에 숫자 2를 할당한다면 데이터 영역에서 숫자 2를 검색합니다. 검색 결과가 없으므로 빈 공간인 @5005에 저장하고 이 주소를 @7103에 저장합니다.

변수 obj1이 바라보는 주소는 동일하지만 객체 내부의 값만 바뀌었습니다.

변수 영역

주소100210031004
데이터이름: obj1 값: @5001

데이터 영역

주소50015002500350045005
데이터@7103 ~1"bbb"2

객체 @5001의 변수 영역

주소7103710471057106
데이터이름: a 값: @5005이름: b 값: @5004

참조형 데이터의 프로퍼티에 다시 참조형 데이터를 할당하는 경우를 중첩 객체라고 합니다.

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~) 그 영역의 주소를 @7104에 저장합니다.

  6. 배열의 요소가 3개 이므로 3개의 변수 공간을 확보하고 각각 인덱스를 부여합니다.(0,1,2)

  7. 데이터 영역에서 숫자 3을 검색해서(@5002) 그 주소를 @8104에 저장합니다.

  8. 데이터 영역에 숫자 4가 없으므로 @5004에 저장하고 이 주소를 @8105에 저장합니다.

  9. 데이터 영역에 숫자 5가 없으므로 @5005에 저장하고 이 주소를 @8106에 저장합니다.

변수 영역

주소100210031004
데이터이름: obj1 값: @5001

데이터 영역

주소50015002500350045005
데이터@7103 ~3@8104~45

객체 @5001의 변수 영역

주소71037104
데이터이름: x 값: @5002이름: arr 값: @5003

배열 @5003의 변수 영역

주소8103710481058106
데이터이름: 0 값: @5002이름: 1 값: @5004이름: 2 값: @5005
obj.arr = "str";

@5006에 문자열 'str'을 저장하고 그 주소를 @7104에 저장합니다.

그르면 @5003은 자신의 참조하는 변수가 하나도 없습니다. 어떤 데이터에 대해 자신의 주소를 참조하는 변수의 개수를 참조 카운트라고 합니다.

참조 카운트가 0인 메모리 주소는 가바지 컬렉터의 수거 대상이 됩니다.

가바지 컬렉터는 런타임 환경에 따라 특정 시점이나 메모리 사용량이 포화 상태에 임박할 떄마다 자동으로 수거 합니다.

변수 영역

주소100210031004
데이터이름: obj1 값: @5001

데이터 영역

주소500150025003(수거 대상)500450055006
데이터@7103 ~3@8104~45"str"

객체 @5001의 변수 영역

주소71037104
데이터이름: x 값: @5002이름: arr 값: @5006

배열 @5003의 변수 영역(수거 대상)

주소8103710481058106
데이터이름: 0 값: @5002이름: 1 값: @5004이름: 2 값: @5005