JavaScript / 비교 연산자 사용법과 ==, === 차이

JavaScript의 비교 연산자는 두 값을 비교해 true 또는 false를 반환합니다. 자료형을 자동 변환하지 않는 비교가 필요하면 ===·!==를 사용하고, 크기를 비교할 때는 입력값이 숫자인지 문자열인지 먼저 확인하세요. 특히 !==는 값과 자료형이 모두 달라야 참인 것이 아니라, 엄격하게 같지 않으면 참입니다.

주요 비교 연산자와 엄격한 비교

연산자 뜻 예제 결과
=== 엄격하게 같음 5 === "5" → false
!== 엄격하게 같지 않음 5 !== 6 → true
== 필요할 때 형 변환 후 같음 5 == "5" → true
!= 형 변환을 포함한 같음 비교의 반대 5 != "5" → false
<·> 작음·큼 2 < 5 → true
<=·>= 작거나 같음·크거나 같음 5 >= 5 → true

===는 자료형이 다르면 거짓을 반환합니다. !==는 그 결과를 반대로 하므로 자료형이 같은 두 숫자라도 값이 다르면 참입니다. 반대로 ==가 모든 자료형의 차이를 무시한다는 설명도 정확하지 않습니다. 연산자가 정한 변환 규칙을 적용하므로, 의도한 비교라면 자료형을 직접 맞춘 뒤 엄격하게 비교하는 편이 흐름을 이해하기 쉽습니다.

5 === 5;   // true
5 !== 6;   // true: 둘 다 숫자지만 값이 다름
5 !== "5"; // true: 자료형이 다름
5 != "5";  // false: 느슨한 같음 비교에서는 같음

객체를 비교할 때는 내부 내용이 같은지가 아니라 같은 객체를 가리키는지가 중요합니다. MDN의 엄격한 같음 비교 설명은 자료형, 숫자와 객체에 적용되는 규칙을 구분합니다.

숫자로 보이는 문자열의 크기 비교

"12" < "2"; // true
12 < 2;     // false
"12" < 2;   // false

두 값이 모두 문자열이면 문자 배열의 순서에 따라 비교합니다. 위 첫 줄은 첫 문자 "1"과 "2"부터 비교하므로 숫자 12와 2의 크기를 판단하는 결과와 다릅니다. 이 문자열 순서는 UTF-16 코드 단위 값에 따른 것이며, 사람의 언어별 정렬 순서와 항상 같지는 않습니다. UTF-16은 JavaScript 문자열에서 사용하는 문자 표현 방식입니다.

문자열과 숫자가 섞이면 숫자 변환이 개입할 수 있습니다. 하지만 자동 변환에 기대면 빈 값이나 변환할 수 없는 문자열을 놓치기 쉽습니다. 입력의 허용 형식을 정하고 변환 결과를 검사한 뒤 숫자끼리 비교하세요. MDN의 크기 비교 설명에는 문자열과 숫자가 섞였을 때의 변환 규칙이 정리돼 있습니다.

같은 입력을 문자열·숫자로 비교하는 전체 예제

아래 전체 코드를 compare-values.html로 저장해 브라우저에서 여세요. 입력란의 value는 문자열이라는 점을 드러내기 위해, 같은 값을 문자열 상태와 숫자로 변환한 상태에서 각각 비교합니다. ==는 차이를 관찰하기 위해 의도적으로 한 번 사용했습니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>문자열과 숫자 비교</title>
</head>
<body>
<h1>입력값 비교</h1>
<label for="left">왼쪽 값</label><input id="left" value="12">
<label for="right">오른쪽 값</label><input id="right" value="2">
<button id="compare" type="button">비교</button>
<button id="restore" type="button">처음 값으로 복원</button>
<pre id="output"></pre>
<script>
const left = document.getElementById("left");
const right = document.getElementById("right");
const output = document.getElementById("output");
function compare() {
  const a = left.value.trim();
  const b = right.value.trim();
  if (a === "" || b === "") {
    output.textContent = "두 값을 모두 입력하세요.";
    return;
  }
  const x = Number(a);
  const y = Number(b);
  if (!Number.isFinite(x) || !Number.isFinite(y)) {
    output.textContent = "유한한 숫자로 바꿀 수 있는 값을 입력하세요.";
    return;
  }
  output.textContent = [
    `문자열 a < b: ${a < b}`,
    `숫자 x < y: ${x < y}`,
    `문자열과 숫자 a == x: ${a == x}`,
    `문자열과 숫자 a === x: ${a === x}`,
    `숫자 x === y: ${x === y}`
  ].join("\n");
}
document.getElementById("compare").addEventListener("click", compare);
document.getElementById("restore").addEventListener("click", () => {
  left.value = "12";
  right.value = "2";
  compare();
});
compare();
</script>
</body>
</html>

기본값 12와 2에서는 문자열의 a < b가 true, 숫자의 x < y가 false로 나옵니다. a == x는 형 변환 때문에 true, a === x는 자료형이 달라 false입니다. 오른쪽 값만 12로 바꾸면 숫자끼리의 x === y는 true가 됩니다.

한쪽 입력을 비우면 빈 값 안내가 나오고, abc나 Infinity를 넣으면 유한한 숫자로 바꿀 수 있는 값을 요구합니다. ‘처음 값으로 복원’ 버튼으로 비교 조건을 되돌릴 수 있습니다. 이 예제의 Number()는 JavaScript가 허용하는 숫자 문자열을 변환하는 실습이며, 결제 금액처럼 십진 표기만 허용해야 하는 입력 양식의 완성된 검증기는 아닙니다.

NaN·객체·연속된 비교의 예외

NaN === NaN;      // false
NaN < 10;         // false
NaN >= 10;        // false
Number.isNaN(NaN); // true

const first = { count: 1 };
const second = { count: 1 };
first === second; // false
first === first;  // true

NaN은 계산이 정상적인 숫자 결과를 만들지 못했음을 나타내는 특수한 Number 값입니다. 비교 연산자만으로 NaN을 판별하려 하지 말고 Number.isNaN()을 사용하세요. 객체 두 개가 같은 내용인지 확인하려면 어떤 속성을 어떤 방식으로 비교할지 정해야 합니다. ===가 객체의 모든 속성을 재귀적으로 비교해 주지는 않습니다.

const value = 15;

// 올바른 범위 비교
const inRange = 10 <= value && value <= 20;
console.log(inRange); // true

수학식처럼 10 <= value <= 20을 쓰면 왼쪽 비교의 불리언 결과를 다시 숫자 20과 비교하게 됩니다. 각 비교를 독립적으로 작성하고 논리 AND 연산자 &&로 결합하세요. 끝점이 포함되는지에 따라 <와 <=를 선택하면 범위 조건도 명확해집니다.