수량 0 대신 10이 나온 이유: JavaScript ||와 ??

수량이 0인데 기본값 10이 나왔다면, ||가 0을 falsy로 판단한 결과일 수 있습니다. 0을 그대로 두고 null·undefined에만 기본값을 쓰려면 ??를 선택합니다. 어떤 값을 ‘없음’으로 볼지가 먼저입니다.

AI가 만든 JavaScript 코드에서 quantity || 10을 발견했다면, 같은 0을 넣어 두 식을 비교해 보세요. 아래는 실제 주문이 아닌 작은 합성 예제입니다.

const quantity = 0;
console.log(quantity || 10); // 10
console.log(quantity ?? 10); // 0
console.log(quantity);       // 0

변수 quantity가 10으로 수정된 것은 아닙니다. ||가 들어간 식의 반환값이 10인 것입니다. 0이 정상 수량인 프로그램이라면, 이 반환값을 다음 처리에 넘기는 지점을 봐야 합니다.

0 토큰과 10이 찍힌 종이 카드를 대비한 설명용 그림
0이 기본값으로 대체되는 상황을 표현한 생성 일러스트입니다. 원본 변수가 바뀌는 실행 화면은 아닙니다.

||와 ??는 ‘없음’의 기준이 다릅니다

MDN의 널 병합 연산자 설명에 따르면 ??는 왼쪽 값이 null 또는 undefined일 때만 오른쪽 값을 반환합니다. ||는 왼쪽 값이 falsy일 때 오른쪽 값을 반환합니다. 여기서 falsy는 불리언 문맥에서 false로 평가되는 값을 뜻합니다.

오른쪽 기본값을 숫자 10으로 고정하고 같은 입력을 비교했습니다. ""는 길이가 0인 문자열이며, 표의 "" 결과도 빈 문자열 그대로라는 뜻입니다.

왼쪽 입력 입력 || 10 입력 ?? 10
0 10 0
false 10 false
"" 10 ""
null 10 10
undefined 10 10
NaN 10 NaN
7 7 7

예를 들어 0이 ‘할인 없음’을 뜻하거나 false가 ‘기능 끄기’를 뜻한다면, 기본값으로 덮어쓰는 것이 의도와 다를 수 있습니다. 반대로 빈 문자열을 표시할 이름이 없는 상태로 취급하기로 했다면 ||가 필요한 코드도 있습니다. 기존 ||를 전부 ??로 바꾸라는 뜻은 아닙니다.

물음표 두 개 연산자에서 0은 0으로 남고 null은 10으로 대체되는 개념 그림
0 보존과 null 대체의 차이를 보여 주는 설명용 생성 이미지입니다. 정확한 입력·출력은 본문의 표를 따릅니다.

기본값을 골랐다고 값 검사까지 끝나진 않습니다

다음 예제는 수량 0, 꺼짐 false, 빈 이름을 모두 그대로 남기기로 한 경우입니다. 각 필드가 null이나 undefined일 때만 기본값을 넣습니다.

function withDefaults(input) {
  return {
    quantity: input.quantity ?? 10,
    enabled: input.enabled ?? true,
    label: input.label ?? "이름 없음"
  };
}
const sample = { quantity: 0, enabled: false, label: "" };
console.log(JSON.stringify(withDefaults(sample)));
// {"quantity":0,"enabled":false,"label":""}

V8의 ?? 기능 설명도 false·0·빈 문자열·NaN은 nullish가 아니므로 그대로 반환한다고 설명합니다. 그대로 반환한다는 것은 그 값이 업무 규칙에 맞는다는 뜻이 아닙니다.

이 함수는 숫자의 범위나 자료형을 검사하지 않습니다. 수량에 NaN을 넣어도 그대로 남고, label에 빈 문자열을 넣으면 ‘이름 없음’으로 바꾸지 않습니다. 실제 앱에서 수량은 0 이상 정수만 받거나 이름은 비어 있으면 안 된다면, 그 조건은 따로 검사해야 합니다. 기본값 연산자가 정해 주는 규칙은 아닙니다.

NaN이 적힌 토큰을 돋보기로 따로 살펴보는 설명용 그림
값을 남기는 일과 그 값의 유효성을 검사하는 일은 다릅니다. 실행 증거가 아닌 생성 설명 그림입니다.

||와 섞을 때는 괄호가 필요합니다

null || undefined ?? 10처럼 괄호 없이 두 연산자를 직접 섞으면 SyntaxError가 납니다. 같은 식을 반복해서 실행하거나, 단순한 값 오류라고 보고 입력만 바꿀 문제가 아닙니다. 어느 부분을 먼저 평가할지 괄호로 구분합니다.

console.log((null || undefined) ?? 10); // 10

이 예제의 괄호 안은 undefined가 되고, 이어 ?? 10이 10을 반환합니다. &&와 ??를 직접 섞을 때도 괄호가 필요합니다. MDN과 V8 모두 이 문법 제약을 설명합니다.

확인한 환경과 수정 뒤 볼 값

2026년 10월 24일, Windows x64의 Node.js v26.5.0(V8 14.6.202.34-node.24)에서 합성 입력으로 확인했습니다. 본문의 코드와 같은 코드를 실행해 0 보존, false·빈 문자열·null·undefined의 결과, 괄호 없는 혼합식의 SyntaxError를 확인했습니다. 실제 주문 처리나 특정 AI 도구의 코드 수정, 모든 브라우저·프레임워크의 동작을 시험한 결과는 아닙니다.

수정 뒤에는 정상 값 하나만 넣지 말고, 해당 필드에서 허용하는 0·false·빈 문자열과 기본값을 써야 하는 null·undefined를 나눠 비교하세요. 무엇을 남겨야 하는지 정하지 않은 채 연산자만 바꾸면, 다른 의도를 가진 코드까지 달라질 수 있습니다.

AI 응답의 형식과 값 검사를 더 나눠 보고 싶다면 JSON 파싱 성공과 합계의 정확성을 구분한 글로 이어갈 수 있습니다. 이번 문제에서는 먼저 ‘없음’의 기준과 원래 남겨야 할 값을 분리하는 것이 핵심입니다.

출처 및 확인일