모든 프로그래밍 언어네는 각자 가진 특징이 있다. 그 중에서 데이터 타입은 언어별로 공통적인 부분도 있지만, 서로 아예 다른 고유적인 부분도 있다. 이 데이터 타입 때문에 개발 공부를 하는 초창기 시절에는 헷갈리는 부분도 많았다... 물론 지금도 가끔 🤦🏻♂️
요즘은 어떤지 모르지만, 내가 학부 시절때는 C언어를 가장 처음 배웠다. 그렇기에 자료형마다 일일이 명시해줘야 하는게 있는데 (int, float, boolean, char ...), 자바스크립트 이놈은 또 다르다. 파이썬이나 자바스크립트와 같은 동적 타입의 스크립트 언어는 자료형을 따로 명시해서 쓰지 않는다! 어떤 자료형들이 있는지 알아보자
자바스크립트의 데이터는 크게 기본형 타입(Primitive Type)과 참조형(Non-Primitive Type)이 있다.
기본형 타입(=원시형 타입)은 크게 6가지로 나뉜다. 각각 숫자(Number), 문자(String), 논리(Boolean), 값이 없음(Null), 정의되지 않음(Undefined), 심볼(Symbol)이다.
자바스크립트에서 숫자는 정수와 유리수를 따로 구분하지 않는다. 자바나 C언어와 같은 컴파일 언어에서는 데이터가 정수(int)인지 유리수(double)인지 반드시 명시해줘야 값 계산이 되는데, 자바스크립트는 자동으로 정수나 유리수로 판정해서 계산을 한다.
// 정수형 변수 a 선언
let a = 10;
// 유리수형 변수 b 선언
let b = 2.5;
// 음수형 변수 c 선언
let c = -0.1;
// 각각 계산
console.log(a + b); // a + b = 12.5
console.log(b * c); // b * c = -0.25
console.log(a / c); // a / c = -100
자바스크립트의 문자(String)는 자바나 C언어의 문자(Char)랑 달리 바로 문자열로 선언할 수 있다. 자바와 C언어에서도 내장 라이브러리를 통해 문자열(String) 변수를 선언할 수 있지만, Char 변수로만 선언하는 것과는 다르다.
또 하나 다른 점은 다른 프로그래밍 언어에서 Char 변수는 '따옴표'를 통해서 만들고, 문자열은 '쌍따옴표'를 사용해서 만들어야 한다. 이를 지키지 않으면 컴파일 과정에서 문법 에러가 나는데, 자바스크립트에서는 둘 중 아무거나 써도 상관없다!
// Java에서 문자 변수 선언
char a = 'a';
char[] say = ['h', 'e', 'l', 'l', 'o'];
String bye = "good bye!";
// JavaScript에서 문자 변수 선언
let a = 'a';
let say = "hello";
let bye = 'good bye!';
불리언은 많이 쓰이는 논리형 변수다. True와 False를 가지고 있어, 조건문에서 특히 많이 쓰인다.
let a = true;
if (a) {
console.log('Success!'); // Success!가 출력됨
} else {
console.log('Fail...');
}
여기서부터는 조금 독특한데, 자바스크립트의 고유 특징이라고 볼 수 있는 부분이다. 물론 자바나 C언에에서도 Null이라는 상태는 존재하지만 자바스크립트처럼 아예 기본형 데이터 타입으로 있지는 않다.
Null로 변수가 선언될 경우 쓰레기값이 들어가는 게 아니라, 의도적으로 해당 변수가 비어있음을 의미하게 된다. 불리언 연산에서는 거짓으로 취급된다. 또 중요한 점은 숫자 '0'이랑 의미와 선언이 아예 다르니 주의하자!
let a = null;
let b = 0;
if (a === b) {
console.log("a is same as '0'");
} else {
console.log(a); // null 출력
}
처음 자바스크립트를 배울 때 제일 의아했던 놈이었다. 변수가 정의되지 않았다가 이 데이터 타입의 정의인데 Null과 엄청 헷갈렸다. 다른 언어에서 변수만 선언하고 값을 대입하지 않았을 때, 쓰레기값이 들어간다고 하는데 자바스크립트에서는 이 경우를 Undefined라는 변수로 선언된다고 보면 된다.
let a = undefined;
let b;
if (a === b) {
console.log(a); // undefined 출력
} else {
console.log('a is not undefined');
}
심볼은 비교적 최근인 ECMAScript6에서 추가된 데이터 타입이다. 내장 객체 함수를 사용해서 변수를 선언하고, 기본형 타입이기 때문에 다른 값과 겹치지 않는 고유값을 가진다.
심볼을 사용하는 이유는 주로 충돌 위험이 없는 객체의 프로퍼티 키를 만들기 위함인데, 아직 잘 안써본 데이터 타입이라 정확히 어떤 부분에서 도움이 되는지는 잘 모르겠다.
const symbolA = Symbol.('symbol');
const symbolB = Symbol.('symbol');
if (symbolA === symbolB) {
console.log('a, b is same symbol');
} else {
console.log('a, b is not same!'); // a, b is not same! 출력
}
참조형 타입은 기본형 타입과 달리 값을 바로 할당하지 않고, 값이 저장된 주소값을 할당한다. C언어의 포인터를 생각하면 된다!
참조형은 대표적으로 객체 타입이 있고, 세부적으로는 배열(Array), 함수(Function), 맵(Map), 셋(Set)등이 있다. 세부적인 사항은 나중에 보고 객체 선언에 대해서만 다뤄본다.
자바스크립트에서 객체를 선언할 때는 반드시 정해진 문법에 따라야 한다. 리터럴로 선언할 때는 {}의 괄호를 사용하고, 그 안에 원하는 프로퍼티 키와 값을 넣는다. 프로퍼티를 추가적으로 선언할 때는 쉼표(,)를 넣어주고, 프로퍼티의 값에는 모든 데이터 타입이 올 수 있다.(객체도 프로퍼티 값으로 들어갈 수 있다)
const a = {
key: 'keyA',
value: 'hi',
obj : {
key: 'keyObj',
value: 'hello'
}
};
console.log(JSON.stringify(a));
// { "key":"keyA", "value":"hi", "obj":{ "key":"keyObj", "value":"hello" } } 출력
console.log(a.key); // keyA 출력
console.log(a.value); // hi 출력
console.log(a.obj); // { "key":"keyObj", "value":"hello" } 출력
오늘 내용중에 헷갈리는 부분만 정리하고 끝내려고 한다.
위 그림을 보자. 0과 Null은 값의 존재 여부로 보면 된다. 데이터를 가리키는 주소는 있는데 실제 그 주소를 가보니 값이 0을 의미하는 숫자면 0이다. 그런데 가보니까 값이 아무것도 없는 상태면 Null이다.
Null과 Undefined는 값이 아닌 주소값의 존재 여부로 보는게 나을것 같다. Null은 해당 값이 아무것도 없지만 값을 가리키는 주소는 있다. 그러나 Undefined는 아예 가리키는 주소도 없다!
[1] : MDN 용어사전 '원시값' 내용 참조
[2] : MDN 용어사전 '객체' 내용 참조