본문으로 건너뛰기
개발 머꼬
개발 노트JavaScript
hohyeon.dev16

기본값을 ||로 줬더니 0과 빈 문자열이 사라진 이유

  • #Common Pitfall
  • #Engineering Note
  • #JavaScript

문제 발생

설정 기본값을 ||로 채웠습니다.

const pageSize = options.pageSize || 20;
const prefix = options.prefix || "MEOKKO";
const showBadge = options.showBadge || true;

사용자가 접두사를 빈 문자열로 지우면 다시 "MEOKKO"가 붙었고, showBadge: false는 아무리 넘겨도 true가 됐습니다.

원인 분석

||의 기준은 "값이 없음"이 아니라 falsy입니다. 0, "", false, NaN이 전부 여기 걸립니다.

MDN은 두 연산자의 차이를 이렇게 정리합니다 — ||는 왼쪽이 falsy이면 오른쪽 피연산자를 반환하고, ??는 왼쪽이 null 또는 undefined일 때만 오른쪽을 반환합니다. 문서의 예제도 같은 함정을 보여줍니다.

const count = 0;
const qty = count || 42;
console.log(qty); // 42, 0이 아니다

??는 falsy 값을 보존합니다 — 문서 예제에서 빈 문자열은 myText ?? "Hi neighborhood"에서 그대로 ''로 남습니다.

해결 방안

  1. "넘기지 않았을 때"의 기본값이면 ??입니다.
const pageSize = options.pageSize ?? 20;
const prefix = options.prefix ?? "MEOKKO";
const showBadge = options.showBadge ?? true;
  1. ||를 쓸 자리도 있습니다. "빈 문자열도 없는 것으로 친다"가 실제 요구라면 ||가 정확합니다. 중요한 건 어느 쪽인지 정하고 쓰는 것이지 ??로 전부 바꾸는 게 아닙니다.

  2. &&/||와 섞을 때는 괄호가 필수입니다. 문서가 명시하듯 괄호 없이 직접 결합하면 SyntaxError입니다.

// null || undefined ?? "foo";   → SyntaxError
(null || undefined) ?? "foo";    // "foo"
  1. 누적 대입에는 ??=가 있습니다. obj.x = obj.x ?? v를 반복해서 쓰지 않습니다.

  2. 구조 분해 기본값과 혼동하지 않습니다. const { pageSize = 20 } = options는 값이 undefined일 때만 적용됩니다. null을 명시적으로 넘기면 기본값이 걸리지 않으므로, API 응답처럼 null이 실제로 오는 입력에는 ??를 함께 씁니다.

  3. 오른쪽은 필요할 때만 평가됩니다. 문서 설명대로 왼쪽이 null/undefined가 아니면 오른쪽 식은 아예 실행되지 않으므로, 기본값 자리에 비싼 함수 호출을 둬도 낭비되지 않습니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.