[javascript] 데이터 타입

진세오·2025년 7월 30일

데이터 타입

    자바스크립트에서 데이터 타입은 크게 두가지가 있습니다.

  1. 기본형(primitve type)
  2. 참조형(reference type)

    기본형에는 Number, String, boolean, null, undefined, Symbol 등이 있으며 참조형에는 객체(Object)가 있으며 객체의 하위 분류로 Array, Function, Date, RegExp, Map, Set 등이 포함됩니다.

    두 타입의 구분은 데이터를 어떻게 메모리에 할당하고, 접근하느냐에 따라 구분 됩니다. 예를 들어 복제를 한다고 했을때 기본형은 값이 담긴 주솟값을 바로 복제하지만, 참조형의 경우 값이 담긴 주솟값이 모여있는 주소가 따로 있고 해당 주소를 복제한다는 차이가 있습니다. 메모리에 할당되는 모습을 보며 좀 더 확실히 알 수 있습니다.

메모리

    컴퓨터에서 가장 작은 메모리 단위는 bit 입니다. 컴퓨터가 데이터를 읽을땐 0 이나 1로 읽는데 1bit에 0, 1 하나씩을 담을 수 있게 됩니다. bit 단위로 데이터를 관리하게 되면 검색을 하거나 불러올때 시간이 오래걸리기 때문에 좀 더 수월하게 관리하기 위해서 byte 라는 단위가 생겼습니다. 1byte는 8bit로, 1byte는 256(2⁸)개의 값을 표현할 수 있게 됩니다.

    과거의 정적언어들(C/C++, JAVA 등)은 메모리 낭비를 최소하 하기 위해 데이터 타입별로 할당하는 메모리 영역이 달랐습니다. 대표적인 예로 short(2byte = 16bit), int(4byte = 32bit)가 있습니다. 그러나 자바스크립트의 경우 컴퓨터의 용량이 커진 상황에서 등장했으므로 메모리 관리를 여유롭게 할 수 있게 되어 형변환을 고려하지 않고 숫자형을 사용할 수 있게 되었습니다.

데이터 할당

할당 과정

let a = 1;

    변수를 선언하고 할당을 한다고 하면 위와 같이 코드를 작성할 수 있습니다. 위의 변수와 식별자는 메모리에 어떻게 저장이 될까요?

    이미지로 표현하면 아래와 같이 식별자(변수명)인 a와 값 1이 구분되어서 저장이 됩니다.

    변수명과, 값이 서로 다른 영역에 저장이 되고 변수명이 저장되는 a의 데이터 공간에 숫자 1의 주소가 값으로 들어가게 됩니다.

    여기서 아래와 같이 a의 할당값을 변경하게 되면 어떻게 될까요?

a = 'aaa';

    그렇다면 aaa 라는 문자열이 숫자 1이 저장되었던 영역 어딘가에 저장이 되고, 그 메모리 주소값이 a가 있는 데이터 공간의 값으로 변경됩니다.

이유

    왜 변수명과 그 값을 따로 저장할까요? 이유는 데이터 변환을 자유롭게 하고, 메모리를 더 효율적으로 관리하기 위해서 입니다. 자바스크립트는 정적언어와 달리 메모리 관리를 여유롭게 할 수 있다고 했습니다. 숫자형에는 8byte(64bit)의 공간을 확보하지만, 문자열은 정해진 규격없이 사용합니다. 문자는 언어마다 필요한 메모리 용량도 다르고 전체 글자수 또한 계속 바뀌기 때문입니다.

    미리 확보한 공간에서 데이터 변환을 하게 된다면 그 공간을 데이터에 맞추어 변경하는 작업을 해야 합니다. 문자열이 계속 뒤에 추가되면 상관없지만, 중간에 삽입이나 삭제가 발생한다면 공간 정리를 위해서 문자열을 이동시키고 삽입하고 다시 주솟값을 연결해야 하는 작업이 필요합니다. 이러한 연산작업을 줄이기 위해서 식별자와 값을 구분해서 저장하게 되었고, 문자열에 변경이 생기면 새로 데이터를 저장하여 그 주소값만 변경하게 되었습니다.

기본형과 참조형

기본형, 불변

    기본형은 불변성을 가지고 있습니다. 여기서 말하는 불변성이란 데이터 영역에서의 불변을 말하게 됩니다.

let a = 'hello';
a = a + ' world';

let b = 2;
let c = b;
c = 3;

    위의 코드를 보면 기본형으로 만든 변수들을 재할당 할 수 있습니다. 이는 변수값이 갖는 데이터는 바뀔 수 있다는 것을 말합니다. 하지만 데이터에서 보면 데이터 자체의 값이 바뀌는 것이아니라 항상 새로 저장되어 식별자(변수명)와 연결되는 것입니다. 간단한 이미지로 본다면 아래와 같습니다.

    기존에 hello가 저장되었던 5002의 데이터가 바뀌지 않고 hello world가 새롭게 5003에 저장되어 그 주소가 식별자 a의 값으로 저장이 됩니다. 둘은 별개의 데이터로 저장이 되는 것입니다. 그렇기 때문에 불변값입니다.

참조형, 가변

    참조형의 경우 어떻게 저장이 될까요? 참조형은 객체, 배열등 변수 안에 여러 값들이 들어가는 형태를 띄게 됩니다.

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

  1. 변수 obj1의 공간을 확보하고 @1003에 obj1의 이름을 저장합니다.
  2. 데이터를 데이터 영역에 저장을 하는데, 저장할 데이터가 복수의 프로퍼티로 이루어져 있어서 그 프로퍼티를 위한 별도의 변수영역을 마련합니다.(@7102~)
  3. 별도의 변수영역의 주소를(@7102~) 데이터영역(@5001)에 저장합니다. 이때 프로퍼티의 개수는 유동적이기 때문에 범위를 지정하지 않습니다.
  4. 데이터 영역에서 숫자 1과 문자열 bbb를 검색합니다. 결과가 없으므로 각각 새로 저장하고(@5002, @5003) 그 주소를 @7102, @7103에 저장합니다.
obj1.a = 2;

    객체 @5001의 변수영역에서 @7102가 값으로 갖는 메모리 주소가 바뀌게 됩니다. 그렇지만 변수영역의 값 @5001은 그대로 유지가 됩니다. 즉, 변수영역이 바라보는 주소를 기준으로 가변과 불변을 구분한다고 볼 수 있습니다.

중접객체

    중첩객체란 참조형 타입의 프로퍼티에 참조형 타입을 할당하는 경우를 말합니다.

let objP = {
  a: 2,
  arr : [1,2,3]
}


  이미지를 보면 또 다른 객체인 arr의 값들도 따로 변수영역을 할당하여 저장하는것을 볼 수 있습니다. 인덱스 값인 0,1,2를 이름으로 하여 새로운 메모리에 저장됩니다.

변수 복사 비교

    마지막으로 변수가 복사되는 것을 메모리 할당을 기준으로 확인하겠습니다.

let a = 10;
let b = a;

let obj1 = {x : 10, y:'zzz'};
let obj2 = obj1;

    변수 b에 a를 복사하고 obj2에 obj1을 복사했습니다.
  변수영역은 서로 다르지만 데이터가 같기 때문에 두 변수에 저장된 메모리 주소가 같아진것을 볼 수 있습니다. 여기서 값을 변경하면 어떻게 될까요?

let a = 10;
let b = a;

let obj1 = {x : 10, y:'zzz'};
let obj2 = obj1;

b = 15;
obj2.x = 20;

    변수영역에서 b의 값은 변경되었지만(@5001 -> @5004) obj2의 값은 (@5002)변경되지 않았습니다.

기본형 b는 숫자 15를 데이터 영역에 저장하고(@5004), b의 주소로 가서 b의 값을 변경합니다. 그러나 참조형의 경우 숫자 20을 데이터 영역에 저장하고(@5005) obj2 주소로 가서 obj2의 값에 해당하는 @5002로 이동, 거기서 x의 주소인 @7102로 이동하여 메모리 주소(값)을 변경하기 때문입니다.

따라서 일치비교를 하게 되면 아래와 같습니다.

a === b // false
obj1 === obj2 // true

마치며

    기본형과 참조형의 가장 큰 차이는 불변성과 가변성입니다. 기본형은 변수영역에 저장된 주소값이 바뀌는데 그것은 데이터가 바뀌지 않기 때문이고, 이를 불변성이라고 합니다. 반대로 참조형은 변수영역에 저장된 주소값이 바뀌지 않고 그 주소가 가지고 있는 데이터의 정보가 바뀌기 때문에 가변성이라고 하는것 입니다.

0개의 댓글