JavaScript · 2장 기본
값의 여덟 가지 종류와 typeof
자바스크립트의 모든 값은 여덟 가지 종류 중 하나예요. 종류마다 할 수 있는 일이 달라서, 값이 무슨 종류인지 아는 것이 버그를 줄이는 첫걸음이에요. 종류를 확인하는 typeof와 그 함정까지 살펴봐요.
01. 값마다 종류가 있어요
자바스크립트 값은 원시값 일곱 가지와 객체로 나뉘어요. 원시값은 숫자 하나, 글자 한 줄처럼 더 쪼갤 수 없는 값이고, 객체는 여러 값을 묶어 담는 그릇이에요. 배열과 함수도 객체의 한 종류예요.
| 종류 | 예 | 무엇에 쓰나요 |
|---|---|---|
| number | 42, 3.14, NaN | 개수 · 가격 · 좌표 등 거의 모든 숫자 |
| bigint | 9007199254740993n | 아주 큰 정수 (끝에 n) |
| string | '하늘', `${n}개` | 글자 |
| boolean | true, false | 예 · 아니요 |
| undefined | undefined | 아직 값이 정해지지 않음 |
| null | null | 일부러 비워 둠 |
| symbol | Symbol('id') | 겹치지 않는 고유한 키 (4장) |
| object | { name: '하늘' }, [1, 2] | 여러 값을 묶은 것 |
자바스크립트 변수에는 종류가 정해져 있지 않아요. 같은 변수에 숫자를 넣었다가 문자열을 넣어도 오류가 나지 않아요(동적 타입). 편하지만, 그만큼 지금 이 값이 무슨 종류인지를 사람이 신경 써야 해요.
02. 숫자 · 문자열 · 불리언
number는 정수와 소수를 구분하지 않아요. 계산할 수 없는 연산은 오류 대신 특별한 값을 돌려줘요. 0으로 나누면 Infinity, 숫자가 아닌 것으로 계산하면 NaN(Not a Number)이에요. number가 정확히 다룰 수 있는 정수는 9007199254740991까지라서, 그보다 큰 정수는 bigint로 써요.
console.log(0.5 * 4, 10 / 0, '사과' * 2); // 2 Infinity NaN
console.log(9007199254740993); // 9007199254740992 — 끝자리가 틀려요
console.log(9007199254740993n); // 9007199254740993n
string은 작은따옴표, 큰따옴표, 백틱(`) 세 가지로 감쌀 수 있어요. 백틱으로 감싼 문자열(템플릿 리터럴)에서는 ${ } 안에 변수나 계산식을 바로 넣을 수 있어서, 문자열을 조립할 때 가장 많이 써요. boolean은 true와 false 두 값뿐이고, 비교 결과(3 > 1)가 이 값이에요.
const name = '하늘';
const count = 3;
console.log(`${name}님, 장바구니에 ${count}개가 있어요`);
console.log(count > 1); // true
03. 비어 있음을 나타내는 두 값
"값이 없다"를 나타내는 값이 두 개예요. undefined는 아직 아무도 값을 정하지 않은 상태예요. 선언만 한 변수, 객체에 없는 속성, 아무것도 돌려주지 않는 함수의 결과가 모두 undefined예요. null은 사람이 일부러 "비어 있음"을 넣은 값이에요.
let selected; // 선언만 했어요
const user = { name: '하늘' };
function noReturn() {}
console.log(selected, user.age, noReturn()); // undefined undefined undefined
let coupon = null; // 쿠폰이 없다는 걸 일부러 표시해요
console.log(coupon); // null
실무에서는 이 둘을 함께 "값 없음"으로 다룰 때가 많아요. 서버에서 온 데이터는 비어 있는 칸을 null로 주는데, 코드 안에서 빠진 값은 undefined가 되거든요. 둘 다 한꺼번에 처리하는 방법은 형 변환과 비교에서 다뤄요.
04. typeof로 종류 확인하기
typeof를 값 앞에 쓰면 종류 이름을 문자열로 돌려줘요. 대부분 위 표의 이름 그대로인데, 두 군데가 달라요.
console.log(typeof 42, typeof 10n, typeof '하늘', typeof true);
console.log(typeof undefined, typeof Symbol('id'), typeof { a: 1 });
console.log(typeof null); // object — 오래된 실수예요
console.log(typeof function () {}); // function
console.log(typeof [1, 2]); // object — 배열도 객체예요
typeof null이'object'인 건 자바스크립트 초기의 실수예요. 이미 많은 코드가 이 동작에 기대고 있어서 고칠 수 없게 됐어요. null인지 확인할 때는value === null로 직접 비교해요.- 함수는 객체지만
typeof는 따로'function'이라고 알려 줘요. "부를 수 있는 값인가?"를 확인할 때 유용해요. - 배열은
'object'로 나와요. 배열인지 확인할 때는Array.isArray(value)를 써요.
아래 일곱 줄의 결과를 먼저 종이에 적어 보고, 실행해서 맞춰 보세요.
console.log(typeof NaN);
console.log(typeof '');
console.log(typeof `${1 + 1}`);
console.log(typeof [] === 'array');
console.log(typeof typeof 1);
console.log(typeof (() => 1));
console.log(Array.isArray([]) && typeof null === 'object');
해답 보기
차례로 number, string, string, false, string, function, true예요.
NaN은 "숫자가 아님"이라는 이름과 달리 number 종류의 특별한 값이에요.typeof는 절대'array'를 돌려주지 않아요. 그래서 넷째 줄은 늘false예요.typeof의 결과는 언제나 문자열이라,typeof typeof 1은'string'이에요.
05. 실전 포인트
- 언제 쓰나요? 함수가 여러 종류의 값을 받을 때(문자열이나 숫자 둘 다 되는 인자 등)
typeof로 나눠 처리해요. 값이 없을 수 있는 자리는null로 표시해서 "깜빡 빠진 값(undefined)"과 구분해요. - 대신 쓰는 것: 배열은
Array.isArray, null은=== null, 숫자가 제대로인지(NaN이 아닌지)는Number.isNaN(5장)으로 확인해요. 종류 실수를 코드 전체에서 막고 싶다면 TypeScript나 JSDoc 타입 표기(3장)를 써요. - 흔한 실수:
typeof value === 'object'로 객체인지 확인하다가null이 섞여 들어오는 것, 9007199254740991보다 큰 ID를 number로 받아 끝자리가 바뀌는 것(이런 ID는 문자열이나 BigInt로 받아요)이에요.
정리
- 값의 종류는 number · bigint · string · boolean · undefined · null · symbol의 원시값 일곱 가지와 object예요.
undefined는 아직 정해지지 않은 값,null은 일부러 비워 둔 값이에요.typeof는 종류 이름을 문자열로 돌려줘요. 단typeof null은'object', 함수는'function'이에요.- 배열은
Array.isArray로, null은=== null로 확인해요.