JavaScript 입력값 검증 체크리스트: Number.isFinite, 범위 제한, 에러 메시지
숫자 입력을 받는 기능(계산기, 견적 폼, 통계 대시보드)은 작은 검증 누락만 있어도 잘못된 결과를 보여주기 쉽습니다.
특히 NaN, Infinity, 빈 문자열, 비정상적으로 큰 수는 UI에서는 정상처럼 보이는데 계산 단계에서 문제를 만들곤 합니다.
이 글은 입력 검증을 복잡한 라이브러리 없이도 재현 가능하게 만드는 기본 체크리스트를 정리합니다.
문제
현장에서 자주 보이는 패턴은 아래와 같습니다.
Number(value)변환만 하고 유효성 검사를 생략- UI
min/max속성만 믿고 로직 방어를 하지 않음 - 에러 메시지를 한 줄로 뭉뚱그려 사용자가 무엇을 고쳐야 할지 모름
이 상태에서는 아래 이슈가 반복됩니다.
- 결과 숫자가 갑자기
NaN으로 깨짐 - 모바일 자동완성/붙여넣기로 의도하지 않은 값이 들어옴
- 운영 중 데이터 품질이 낮아져 신뢰도가 떨어짐
설명
입력 검증은 보통 다음 3단계로 설계하면 안정적입니다.
- 형식 검사: 숫자로 변환 가능한지 확인
- 범위 검사: 허용 구간을 벗어나는지 확인
- 피드백 분리: 어떤 필드가 왜 잘못됐는지 명확히 표시
핵심은 isNaN 대신 Number.isFinite를 우선 사용하는 것입니다.
Number.isFinite(n)은 실제 숫자이면서 유한한 값만trueNaN,Infinity,-Infinity를 모두 걸러냄
또한, UI의 min/max는 보조 장치로 보고, 계산 직전 로직에서 한 번 더 clamp(상하한 보정)하는 편이 안전합니다.
예시
아래는 월 납입금 계산 전에 입력값을 검증/보정하는 간단한 예시입니다.
function clamp(value, min, max) {
return Math.min(max, Math.max(min, value));
}
function parseMoney(raw) {
const n = Number(raw);
return Number.isFinite(n) ? n : null;
}
function validateLoanInput({ principal, annualRate, months }) {
const p = parseMoney(principal);
const r = parseMoney(annualRate);
const m = parseMoney(months);
const errors = [];
if (p === null || p <= 0) errors.push('대출원금은 0보다 큰 숫자여야 합니다.');
if (r === null) errors.push('연이율은 숫자로 입력해야 합니다.');
if (m === null || !Number.isInteger(m)) errors.push('기간은 정수(개월)여야 합니다.');
if (errors.length > 0) {
return { ok: false, errors };
}
return {
ok: true,
value: {
principal: clamp(p, 10000, 10000000000),
annualRate: clamp(r, 0, 100),
months: clamp(m, 1, 600)
}
};
}
이 구조의 장점은 다음과 같습니다.
- 계산 함수는 “검증 완료 데이터”만 받으므로 단순해짐
- 필드별 메시지 분리로 사용자가 즉시 수정 가능
- 붙여넣기/자동완성 등 비정상 입력에도 결과 일관성 유지
요약
입력 검증의 기본은 복잡하지 않습니다.
Number.isFinite로 숫자 유효성 확인- 계산 직전
clamp로 범위 보정 - 필드별 에러 메시지로 수정 경로 제공
이 세 가지를 지키면 폼/계산기 기능의 안정성과 신뢰도를 동시에 높일 수 있습니다.