[코어 자바스크립트] 01. 데이터 타입

자바스크립트를 좀 더 깊게 이해하기 위해 코어 자바스크립트 책으로 공부를 시작했다.
알게된 내용을 복습하기 위해 글로 정리하려 한다.

이번 글은 코어 자바스크립트 책의 1장(데이터 타입)을 공부한 내용이다.

자바스크립트가 데이터를 어떻게 처리하는지, 기본형 데이터와 참조형 데이터의 차이가 무엇인지 이해할 수 있었다. 😬


0. 데이터 타입의 종류

자바스크립트의 데이터 타입에는 크게 두 가지가 있다.


1. 변수 선언과 데이터 할당

  • 변수 : 변경 가능한 데이터가 담길 수 있는 공간
  • 식별자 : 어떤 데이터를 식별하는 데 사용하는 이름, 변수명

a라는 변수를 선언하고, ‘abc’ 데이터를 할당하면, 컴퓨터가 어떤 과정을 통해 처리하는지 확인해 보자.

//

let a = "abc";

//

image

데이터의 성질에 따라 변수 영역데이터 영역으로 구분해 생각하자.

  1. 변수 영역에서 빈 공간(@1003)을 확보한다.
  2. 확보한 공간의 식별자(이름)를 a로 지정한다.
  3. 데이터 영역의 빈 공간(@5004)에 문자열 ‘abc’를 저장한다.
  4. 변수 영역에서 a라는 식별자를 검색한다. (@1003을 찾음)
  5. 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입한다.

왜 변수 영역에 값을 직접 대입하지 않고 굳이 한 단계를 더 거치는 걸까?

그 이유는 (1) 데이터 변환을 자유롭게 할 수 있게 함과 동시에 (2) 메모리를 더욱 효율적으로 관리하기 위함이다.

아래 예시로 이헤헤 보자.

image

기존 a에 할당 되어 있던 ‘abc’를 ‘abbbc’로 변경했다.

자바스크립트는 숫자형 데이터는 64비트(8바이트)의 공간을 확보하지만, 문자열은 특별히 정해진 규격이 없다. 한글과 영어가 한 글자마다 필요로 하는 용량이 다르며, 전체 글자수도 고정되어 있는 게 아니기 때문이다.

만약 확보된 공간에서 데이터를 변경하려면 그 공간을 변화된 데이터 크기에 맞게 늘리는 작업이 필요할 것이다. ‘abc’를 ‘abcdef’로 바꾸는 것처럼 마지막에 추가되는 작업은 어렵지 않더라도, ‘abc’를 ‘abbbbc’로 바꾸는 것처럼 중간에 삽입을 해야 한다면 컴퓨터가 처리해야 할 연산이 많아질 것이다.

따라서 변수에 할당된 데이터를 변경할 때, 새로운 데이터를 별도의 공간에 저장하고 그 주소를 연결한다.

또한, 500개의 변수에 똑같은 숫자 5를 할당하는 상황을 생각해 보자. 각각의 변수마다 데이터를 할당하려면 숫자 데이터가 8바이트를 필요로 하기 때문에 (500*8)바이트를 써야 한다.

그 대신 5를 별도의 공간에 한 번 저장하고 해당 주소만 가지고 있는다면, 주소 공간의 크기가 1이라고 가정했을 때 (500 + 8)바이트만 사용해도 된다. 이처럼 변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아진다.


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

2-1. 불변값

변수(Variable)와 상수(Constant)를 구분하는 성질은 ‘변경 가능성’이다. 즉, 바꿀 수 있으면 ‘변수’이고, 바꿀 수 없으면 ‘상수’이다. 그래서 불변값과 상수가 같은 개념이라고 오해할 수 있는데, 명확하게 구분해야 한다.

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

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

기본형 데이터를 변수에 할당하는 과정을 살펴보자.

//

let b = 5;
let c = b;
c = 7;

//

첫번째, 두번쨰 줄에서 b와 c 변수 선언을 하고 데이터를 할당했다. 그럼 아래 그림처럼 메모리에 저장될 것이다.

image

세번째 줄에서 c의 데이터 값을 변경했다. 좀 전에 설명한 것처럼 값이 변경되지 않고, 7이란 데이터가 메모리에 있는지 확인한 후에 없으면 새로 저장한다.

image

이처럼 변수의 값을 다른 값으로 변경할 수 없고 새로 만드는 동작을 통해서만 이뤄지는 특징이 불변값의 성질이다. 한 번 만들어진 값은 가비지 컬렉팅을 당하지 않는 이상 영원히 변하지 않는다.

어떤 데이터에 대해 자신의 주소를 참조하는 변수의 개수를 참조 카운트라고 한다. 참조 카운트가 0인 메모리 주소는 가비지 컬렉터(garbage collector, GC)의 수거 대상이 된다.

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

2-2. 가변값

참조형 데이터를 변수에 할당하는 과정을 살펴보자.

//

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

//

image

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

기본형 데이터와의 차이는 객체의 변수(프로퍼티) 영역이 별도로 존재한다는 점이다. 객체가 별도로 할애한 영역은 변수 영역일 뿐 데이터 영역은 기존의 메모리 공간을 그대로 활용하고 있다. 데이터 영역에 저장된 값은 모두 불변값인데, 변수는 다른 값을 얼마든지 대입할 수 있다는 특징을 가지고 있다. (@5001에 변수가 할당되어 있다.)
그래서 흔히 참조형 데이터가 불변(immutable)하지 않다고(가변값이라고) 하는 것이다.

참조형 데이터의 프로퍼티를 재할당하면 어떻게 동작하는지 알아보자.

// ...

obj1.a = 2;

//

image

위에서 선언했던 obj1의 프로퍼티인 a의 값을 1에서 2로 변경했다. 내부 프로퍼티는 숫자형 데이터이기 때문에 불변성을 가지고 있고, 그래서 @5005에 2를 새로 저장한다. (2를 탐색한 뒤에 있으면 재활용, 없으면 새로 만듦)

@7103에 @5005 주소값을 다시 저장한다. 이때 주목해야 할 점은 @1003에 있는 주소값은 바뀌지 않았다는 것이다. 즉, 새로운 객체가 만들어지지 않고, 객체 내부 값만 변경되었다.

2-3. 변수 복사 비교

let a = 10;
let b = a;

let obj1 = {
    c: 10,
    d: "ddd",
};
let obj2 = obj1;

위 코드를 실행하면 아래처럼 메모리에 데이터가 저장될 것이다.

image

이때 값을 변경하면 어떻게 될까?

기본형 데이터와 참조형 데이터의 차이점에 집중하며 아래 과정을 살펴보자.

// ...

b = 15;
obj2.c = 20;

//

image

기본형 데이터를 복사한 변수 b의 값을 바꿨더니 @1002의 값이 달라진 반면, 참조형 데이터를 복사한 변수 obj2의 프로퍼티의 값을 바꿨더니 @1004의 값이 달라지지 않았다. 즉, 변수 a와 b는 서로 다른 주소를 바라보게 되었으나, 변수 obj1과 obj2는 아직 같은 객체를 바라보고 있는 상태이다.

이 결과가 기본형과 참조형 데이터의 가장 큰 차이점이다.

만약 객체 자체를 변경하면 어떻게 될까?

let obj1 = {
    c: 10,
    d: "ddd",
};
let obj2 = obj1;

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

image

obj2에 새로운 객체를 할당했기 때문에 메모리의 데이터 영역의 새로운 공간에 새 객체가 저장되었고, obj2가 그 주소를 저장하면서 obj1과 다른 주소를 가지고 있게 되었다.

참조형 데이터인 객체를 변경하면 값이 달라진다는 걸 확인했다. 즉, 참조형 데이터가 ‘가변적’이라고 하는 건 참조형 데이터 자체를 변경할 경우가 아닌 내부 프로퍼티를 변경할 때만 성립한다.



📚 참고

코어 자바스크립트 (저자: 정재남)

Joie-Kim

Joie-Kim

배운 것을 기록하는 습관! ✍️

comments powered by Disqus
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin pinterest medium vimeo stackoverflow reddit quora quora