JavaScript의 데이터 타입은 두 종류가 있다. 두 타입의 차이점에 대해 알아보자.
pass by value
원시타입은 메모리 영역에서 값을 변경할 수 없는 immutable한 특징이 있다.
자바스크립트의 원시 타입은 콜스택에 저장되고 immutable(변경 불가능)하다.
자바스크립트에서 원시 타입의 데이터는 변수에 할당될 때 고정된 크기로 값을 메모리에 저장하고 저장된 값을 변수가 직접적으로 가리키고 있는 형태를 띈다.
변수 a에 재할당이 일어난 경우, a에 할당된 10의 값이 20으로 변하는 것이 아니라 메모리 상에 20을 새로 생성하고 a는 20을 가리킨다.
let a = 10;
a = 20; // 재할당
console.log(a); // 20
이처럼 원시타입 데이터는 재할당이 일어난 경우 메모리 영역에 저장된 값 자체를 바꾸지 않고, 새로 메모리를 할당받아 값을 저장하기 때문에 immutable하다고 볼 수 있다.
자바스크립트 원시 타입의 종류에는 number
boolean
null
undefined
string
, ES6 이후로 추가된 symbol
이 있다.
이 중에서 몇 가지만 자세하게 알아보자
문자열은 배열과 같이 인덱스를 통해 값에 접근할 수 있다. 이와 같은 특징이 있는 데이터를 유사 배열이라고 한다.
let str = 'string';
console.log(str[0]); // 's'
그러나 인덱스로 접근한 값을 변경할 수는 없다. 앞서 말했듯 원시 타입의 데이터는 메모리상에 존재하는 기존 값을 변경할 수 없기 때문이다. 한 번 생성된 문자열은 read only
다.
let str = 'string';
str[0] = 'f'; // 에러는 발생하지 않는다.
console.log(str); // 'string'
자바스크립트 엔진은 선언 이후 값을 할당받지 않은 변수에 대해 undefined
로 초기화한다.
let empty;
console.log(empty); // undefined
따라서 개발 중 undefined를 마주칠 땐 변수가 선언은 되었지만 값이 할당된 적은 없다는 것으로 받아들이면 된다.
임의로 undefined
를 남발한다면 위와 같은 자바스크립트 취지에 어긋난다. 따라서 값이 없다는 것을 명시하고 싶을 땐 null
을 할당하는 것이 맞겠다.
자바스크립트는 대소문자를 구별하기 때문에 null
, Null, NULL은 모두 다른 값이다.
한편 자바스크립트 엔진은 Garbage Collector를 이용해 사용되지 않는 값을 알아서 제거하는데, 메모리 상에서 아무도 참조하고 있지 않는 변수를 찾아내 제거한다.
이 때 null
을 이용해 의도적으로 변수의 참조 정보를 제거하면 해당 값은 Garbage Collector가 알아서 제거할 것이다.
let garbage = 'Hi';
garbage = null; // 참조 정보 제거
null
의 타입을 출력하면 object가 뜨는데, 이는 자바스크립트 설계상의 오류다. 따라서 null
값인지 확인하고 싶을 때는 일치 연산자를 사용하는 것이 좋겠다.
let isNull = null;
console.log(typeof isNull === null); // false
console.log(null === null); // true
ES6에서 새롭게 추가된 타입이다. 객체에 고유한 키를 부여해 다른 코드와 충돌하지 않도록 할 때 쓰인다.
Symbol("foo") === Symbol("foo"); // false
pass by reference
객체 타입은 동적으로 변할 수 있어 런타임시 메모리 공간을 확보하기 위해 메모리의 힙 영역에 저장된다.
데이터 자체는 힙에 저장되고 콜스택에는 힙에 할당된 메모리의 주소값이 들어있다.
따라서 자바스크립트 엔진이 값을 참조할 땐 콜스택에 있는 메모리 주소값을 참조해 힙에 있는 실제 데이터에 접근한다.
데이터 복사가 일어났을 경우 참조하고 있는 주소 값을 할당 받기 때문에 힙 영역의 같은 데이터를 가리키고 있다
const arry1 = [1, 2, 3];
const arry2 = arry1;
arry1.push(4);
console.log(arry1); // [1, 2, 3, 4]
console.log(arry2); // [1, 2, 3, 4]
참조 타입의 종류에는 배열
, 객체
, 함수
등이 있다.