자바스크립트(Javascript)에서 자료형(Data Type)이란, 프로그래밍 언어로 조작 할 수 있는 값의 유형을 말한다. 자바스크립트에는 총 8가지 자료형이 존재하고, 원시 타입과 참조 타입으로 크게 나뉘고 7가지 원시 타입, 1가지의 참조 타입이 존재한다.
원시 타입
Number
BigInt
String
Null
Undefined
Boolean
Symbol
참조 타입
Object
원시 타입은 값이 생성된 후에 그 값을 변경 할 수 없다.
값을 복사하여 전달하는 pass by value
방식이다.
각 타입마다 할당받는 메모리의 크기가 다르다. 이를 통해 한정된 메모리 공간을 효율적으로 사용 할 수 있다. 그리고 할당 가능한 값의 유효 범위를 한정 할 수도 있다.
자바스크립트에서는 숫자를 표현하는 두가지 내장 타입을 가지고 있다.
Number
과 BigInt
이다.
자바스크립트의 MAX_VALUE
값을 2^1024 이지만, MAX_SAFE_INTEGER
의 값은 2^53-1 값으로 훨씬 낮다. 안전범위 밖에 큰 수를 변수에 저장 할 수는 있지만 정확성을 보장하긴 힘들기 때문에 BigInt
가 필요하다.
BigInt
타입은 Number
타입의 안전범위 밖에 큰 정수를 저장하고 연산 할 수 있다.
BigInt
는 정수 끝에 n
을 추가하거나 생성자를 호출하는 방식으로 생성 가능하다.
다만 BigInt
와 Number
는 혼합해 사용 할 수 없고, Math
객체 메소드를 사용 할 수 없다.
const BiggestInt1 = 9007199254740991n;
const BiggestInt2 = BigInt(9007199254740991);
let str = 'Hello';
str = 'world';
자바스크립트의 문자열의 값은 불변하다.
하지만 위 코드는 정상 작동하는걸 우리는 알 수 있다.
문자열 자체는 변경이 불가능 한 것이 맞다.
2번째 구문이 실행되면 기존의 Hello
가 수정되는 것이 아닌, 새로운 문자열 world
가 생성되는 것이다.
그 뒤 변수 str
은 Hello
대신 world
를 표시하도록 변경되는 것이다.
const str = 'string';
for (let i = 0; i < str.length; i++) {
console.log(str[i]);
}
문자열은 유사 배열로 배열처럼 인덱스를 통해 접근 할 수 있다. (배열 메소드 가능)
배열처럼 보이지만 사실 key가 숫자이고 length의 값을 가지고 있는 객체이다.
대표적인 예시로 객체, NodeList, HTMLCollection 등이 있다.
배열이 아니므로 배열 메소드를 사용 할 수 없다.
대신 Array.from()
을 통해 유사 배열을 배열로 복사하여 메소드를 사용하게끔 만들 수 있다.
오로지 true
, false
값으로만 나타내는 타입을 불리언 타입이라고 한다.
자바스크립트에서는 빈 문자열, 0, null, undefined, NaN 등의 값들은 false
로 간주하게 된다.
참고 : https://developer.mozilla.org/ko/docs/Glossary/Falsy
undefined
타입의 값으로는 undefined
가 유일하다.
자바스크립트 엔진에서는 선언 이후 값이 할당되지 않은 변수를 undefined
로 초기화한다.
이러한 의미 때문에 개발자가 의도적으로 undefined
를 사용하는 것을 권장하지 않으며, 의도적으로 값이 없다는 것을 명시하고 싶다면 null
을 사용하면 된다.
null
타입의 값으로는 null
이 유일하다.
null
은 변수에 값이 없다는 것을 명시하는 용도로 사용된다.
null
의 할당은 변수에 연결된 메모리 주소 참조를 제거하겠다는 의미이기도 하다.
이 후 자바스크립트 엔진은 참조하지 않는 메모리 영역에 대해 가비지 컬렉션을 수행하게 된다.
또한 null
에는 유명한 버그가 존재한다.
console.log(typeof null); // "object"
typeof
연산자를 사용하게 되면 object
를 반환한다. 이는 명백한 버그이지만, 수정하게되면 null
을 사용하는 수많은 스크립트에 문제가 발생할 것으로 예상되어 고칠 수 없게 되었다.
ES6 이후 새롭게 추가된 원시 타입이다.
Symbol
은 이름의 충돌 위험이 없는 고유한 값을 만들기 위해 사용한다.
그래서 이를 객체의 프로퍼티 키로 활용할 수도 있다.
const key = Symbol('key');
console.log(typeof key); // symbol
const obj = {};
obj[key] = 'value';
console.log(obj[key]); // value
원시 타입을 제외한 거의 모든 것(객체, 배열, 함수 등)을 참조 타입으로 볼 수 있다.
참조 타입은 프로퍼티를 추가, 변경, 삭제가 가능하다는 특징이 있고, 이러한 성질 때문에 필요한 메모리 공간을 예측하기가 어렵다는 점이 있다.
참조 타입을 변수에 할당하게되면 참조 타입은 메모리의 힙(Heap) 이라는 영역에 저장된다.
그리고 변수는 그 참조값(address)을 가지게 된다.
그래서 객체는 값을 전달할 때 값을 복사하지 않고 참조값을 전달 pass by reference
한다.