[01 데이터 타입]
01 데이터 타입의 종류
데이터 타입에는 크게 기본형(원시형, primitive type), 참조형(reference type) 2가지가 존재
기본형은 숫자(number), 문자열(String), 불리언(boolean), null, undefined 등이 있으며 ES6에서 심볼(Symbol)이 추가됨
참조형은 객체(object), 배열(Array), 함수(Function), 날짜(Date), 정규표현식(RegExp) 등과 ES6에서 추가된 Map, WeakMap, Set, WeakSet 등이 있음
기본형과 참조형을 구분하는 기준은 값을 복제하는가, 주소값을 복제하는가 차이
기본형은 불변성(immutability)를 띔
02 데이터 타입에 관한 배경 지식
1-2-1 메모리와 데이터
컴퓨터는 모든 데이터를 0과 1로 바꿔 기억함
하나의 메모리 조각을 비트라 하며, 메모리는 매우 많은 비트들로 구성되어 있음
각 비트는 고유한 식별자(unique identifier)를 통해 위치를 확인할 수 있음
자주 사용하지 않을 데이터를 표현하기 위해 빈 공간을 남겨놓기 보다는, 표현 가능한 개수에 제약이 따르더라도 크게 문제가 되지 않을 적정한 공간을 묶기로 함
이 묶인 공간의 단위가 바이트(byte)
1바이트는 8개의 비트로 구성되어 1 바이트는 총 256개의 값을 표현할 수 있음
C/C++, 자바 등의 정적 타입 언어는 메모리의 낭비를 최소화하기 위해 데이터 타입별로 할당할 메모리 영역을 2바이트, 4바이트 등으로 나누어 정함(int형, short형 등…)
한편 메모리 용량이 과거보다 월등히 커진 상황에 등장한 자바스크립트는 상대적으로 메모리 관리에 대한 압박에서 자유로움
숫자의 경우 정수형인지 부동소수형인지를 구분하지 않고 8바이트를 확보함
각 비트는 고유한 식별자를 지님, 바이트 역시 시작하는 비트의 식별자로 위치를 파악 가능함
모든 데이터는 바이트 단위의 식별자, 메모리 주소값(memory address)을 통해 서로 구분하고 연결 할 수 있음
1-2-2 식별자와 변수
보통 변수(variable)와 식별자(identifier)를 혼용하는 경우가 많음
변수는 ‘변할 수 있는 무언가’를 뜻하며 여기서 무언가란 데이터를 망함
식별자는 어떤 데이터를 식별하는데 사용하는 이름, 즉 변수명
03 변수 선언과 데이터 할당
1-3-1 변수 선언
var a;
예제를 말로 풀면 “변할 수 있는 데이터를 만든다. 이 데이터의 식별자는 a로 한다”
변할 수 있는 데이터니 선언할 때는 undefined 이더라도 나중에 다른 값으로 바꾸면 됨
변수란 변경 가능한 데이터가 담길 수 있는 공간 또는 그릇 이라고 생각 할 수 있음
1-3-2 데이터 할당
예시 1
var a;
a = ‘abc’;
예시 2
var a = ‘abc’;
선언과 할당을 나누든 같은 줄에 명령하든 자바스크립트 엔진은 결국 같은 동작을 수행함
할당 과정에서 a라는 이름을 가진 주소를 검색해서 문자열 ‘abc’를 할당할 것 같지만, 실제로는 문자열 ‘abc’를 저장하지는 않음
데이터를 저장하기 위핸 별도의 메모리 공간을 다시 확보해서 문자열 ‘abc’를 저장하고, 그 주소를 변수 영역에 저장하는 방식으로 이뤄짐
데이터 할당의 전체 흐름은 다음과 같음
1. 변수 영역에서 빈 공간(@1003)을 확보한다.
2. 확보한 공간의 식별자를 a로 지정한다.
3. 데이터 영역의 빈 공간(@5004)에 문자열 ‘abc’를 저장한다.
4. 변수 영역에서 a라는 식별자를 검색한다.(@1003)
5. 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입한다.
변수 영역에 값을 직접 대입하지 않는 이유는 데이터 변환을 자유롭게 하고, 메모리를 더욱 효율적으로 관리하기 위한 고민의 결과
숫자와 달리 문자열은 정해진 규격이 없음
만약 미리 확보한 공간 내에서만 데이터 변환이 가능하다면, 변화한 데이터를 다시 저장하기 위해선 ‘확보된 공간을 변환된 데이터 크기에 맞게 늘리는 작업’이 선행되야 함
해당 공간이 메모리 상의 중간에 있다면 해당 공간보더 뒤에 저장된 데이터를 뒤로 옮기고, 이동시킨 주소를 각 식별자에 다시 연결해야함
효율적으로 문자열 데이터의 변환을 처리하려면 변수와 데이터를 별도의 공간에 나누어 저장해야함
이전 데이터 할당 흐름에서 ‘abc’ 뒤에 ‘def’를 추가하라고 하면, ‘abc’가 저장된 공간에 ‘abcdef’를 할당하는 대신 ‘abcdef’ 라는 문자열을 새로 만들어 별도의 공간에 저장하고, 그 주소를 변수 공간에 연결함
만약 500개의 변수를 생성하고 모든 변수에 숫자 5를 할당하는 경우
각 변수를 별개로 인식하려면 500개의 변수 공간을 확보해야함
각 변수 공간마다 매번 5를 할당하려하면 개당 8바이트 즉 총 4000(500 8) 바이트를 써야함
대신 5를 별도의 공간에 한번만 저장하고 해당 주소만 입력하는 경우, 주소 공간의 크기가 2 바이트인 경우 1008(500 2 + 8) 바이트만 이용하면 됨
변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아짐
[질문]
값이 바뀔 떄 매번 새로운 공간을 만드는 경우, 기존에 확보한 데이터 공간은 어떻게 되는가?
예시)
var a; // 변수 공간에 a 생성
a = 1 // 데이터 공간에 1 생성 후 주소값을 a에 값으로 넣어줌
a = a + 1 // 데이터 공간에 2 생성 후 주소값을 a에 값으로 넣어줌
// 기존에 데이터 공간에 생성 된 1은 변수 공간에 연결이 되지 않음
// 가비지 컬렉터 대상이 되어 메모리 관리가 됨
→ 변수 영역에 연결되지 않은 데이터 주소가 있는 경우 가비지 컬렉션의 대상이 되어 메모리가 관리됨
Garbage Collection
쓸모 없어진 객체가 차지하는 메모리를 자동으로 해제하는 것