학습 공간 개념 · 판단 · 실험

Frontend Performance Lab

JavaScript

값과 타입, 변환을 구분하기

타입은 변수가 아니라 값에 붙으며, 연산자마다 값을 변환하는 규칙이 다르므로 변환과 검증을 분리해 다룹니다.

이럴 때 필요해요

사용자 입력이나 외부 데이터를 다룰 때 암묵적 형변환 때문에 생기는 예상치 못한 버그를 예방할 수 있습니다.

어떻게 동작하나요?

하나의 변수에 처음에는 숫자 1을 넣었다가 나중에 문자열 'one'을 다시 넣어도 JavaScript에서는 문법 오류가 나지 않습니다. 변수 칸 자체에 타입이 영구적으로 고정되지 않고, 실행 시점에 들어 있는 값에 따라 타입이 정해지는 동적 타입(Dynamic Typing) 언어이기 때문입니다. 값의 종류는 크게 변경 불가능한 7가지 원시 타입(undefined, null, boolean, number, bigint, string, symbol)과, 프로퍼티를 가지며 참조로 다루는 객체 타입(일반 객체, 배열, 함수 등)으로 나뉩니다.

변수를 다룰 때는 이름을 스코프에 등록하는 '선언', 첫 값을 정하는 '초기화', 값을 대입하는 '할당'을 구분해야 합니다. let value;가 실행된 뒤에는 value가 undefined로 초기화되지만, let이나 const 선언문에 도달하기 전 구간인 TDZ(일시적 사각지대)에서 읽으려고 하면 undefined가 나오는 대신 ReferenceError가 발생합니다. 또한 값이 비어 있음을 나타낼 때도 엔진이 기본으로 돌려주는 undefined와 개발자가 의도적으로 비워 두었음을 표현하는 null을 구분해 사용합니다. 참고로 typeof null이 'object'를 반환하는 것은 초기 JavaScript부터 남아 있는 역사적 동작입니다.

같은 모양의 값이라도 어떤 연산자를 쓰느냐에 따라 결과가 달라집니다. 예를 들어 '12' + 1은 문자열 연결이 일어나 '121'이 되지만, '12' - 1은 숫자로 변환되어 11이 됩니다. 이처럼 연산자가 알아서 타입을 바꾸는 암묵적 형변환에 의존하면 버그가 생기기 쉬우므로, Number(raw)처럼 의도를 드러내어 명시적으로 변환한 뒤 Number.isFinite()로 유효한 숫자인지까지 검증하는 습관이 중요합니다. 값을 비교할 때도 타입을 임의로 바꾸지 않는 ===를 기본으로 사용하고, 기본값 처리에는 null과 undefined만 걸러내는 ??(nullish 병합) 연산자를 활용합니다.

코드 예제

동작을 설명하는 읽기 전용 예제입니다.

example.js
const raw = '12';
const count = Number(raw);
if (!Number.isFinite(count)) throw new Error('숫자가 필요합니다');
console.log(count + 1); // 13
console.log('12' + 1); // '121'
javascript · 읽기 전용5줄

문자열 입력을 숫자로 명시적 변환한 뒤 유효성을 먼저 검증하고, + 연산자가 피연산자 타입에 따라 숫자 덧셈과 문자열 연결로 다르게 동작함을 확인합니다.

자주 헷갈리는 포인트

  • 동적 타입 언어라는 말을 타입 규칙이 아예 없는 언어라는 뜻으로 오해하지 않습니다.
  • 선언되지 않은 이름에 typeof를 쓰면 'undefined'가 반환되지만, TDZ에 있는 let/const 변수에 typeof를 쓰면 ReferenceError가 발생합니다.

내 말로 설명해 보기

값이 undefined인 변수와 아예 선언되지 않은 식별자는 실행 결과에서 어떻게 구분할 수 있을까요?

함께 읽으면 좋은 개념

관련 면접 질문 5개

JavaScript는 어떤 실행·타입 특성을 가진 언어인가요?

JavaScript는 함수와 객체를 일급 값으로 다루며 실행 중에 값의 타입이 결정되는 동적 타입 언어입니다. 프로토타입 기반의 객체 모델을 사용하고, 명령형·함수형 등 다양한 스타일로 코드를 작성할 수 있습니다. 흔히 함께 쓰는 DOM이나 타이머는 언어 자체 기능이 아니라 브라우저 같은 호스트 환경이 제공하는 API이며, 기본적으로 하나의 메인 스레드 흐름에서 동작하므로 병렬 계산이 필요할 때는 Web Worker 같은 별도 실행 환경을 구분해 사용합니다.

꼬리질문과 참고자료 →

JavaScript의 원시 타입과 객체 타입은 어떻게 구분하나요?

JavaScript의 값은 undefined, null, boolean, number, bigint, string, symbol의 7가지 원시 타입과 나머지 객체 타입으로 나뉩니다. 원시값은 그 자체를 변경할 수 없는 불변 값이고, 배열과 함수를 포함한 객체 타입은 프로퍼티를 가지며 참조를 통해 내부 상태를 바꿀 수 있습니다. 또한 숫자를 다루는 number는 정수와 부동소수점을 함께 표현하지만 안전하게 표현할 수 있는 정수 범위가 정해져 있어, 아주 큰 정수는 bigint로 구분해 다룹니다.

꼬리질문과 참고자료 →

암묵적·명시적 형변환에서 무엇을 주의해야 하나요?

명시적 형변환은 Number(), String(), Boolean() 등으로 변환 의도를 코드에 직접 드러내는 방식이고, 암묵적 형변환은 연산자나 조건문 규칙에 따라 엔진이 타입을 자동으로 바꾸는 동작입니다. 예를 들어 + 연산자는 피연산자 중 하나가 문자열이면 문자열 연결을 수행하지만 -, *, /는 숫자로 변환을 시도하므로 입력값의 타입을 미리 확인해야 합니다. 실무에서는 예기치 않은 변환을 막기 위해 비교 시 ===를 사용하고, 숫자로 변환한 뒤에는 Number.isFinite() 등으로 NaN 여부를 함께 검증합니다.

꼬리질문과 참고자료 →
나머지 질문 2개

공식 참고 자료

← JavaScript