Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 null과 0을 비교하면 왜 이런 결과가 나올까?

JavaScript에서 falsy(거짓 같은) 값을 다루다 보면 null0의 비교에서 의외의 결과를 마주하게 됩니다. 두 값을 비교해 보면, 크다(>), 작다(<), 같다(==) 연산자에서는 모두 Boolean false가 반환되지만, 크거나 같다(>=) 연산자에서는 Boolean true가 반환됩니다.

여기서 자연스럽게 이런 의문이 생깁니다. 어떤 값이 0보다 크지도 않고, 0과 같지도 않은데, 어떻게 0보다 크거나 같을 수 있을까요?

예제 1: >, <, == 비교

다음 예제에서는 null과 0 사이에서 크다, 작다, 같다는 세 가지 조건을 차례로 확인합니다. 세 경우 모두 해당하지 않으므로 최종적으로 else 블록의 문장이 출력됩니다.

<html>
<body>
    <script>
        if(null > 0){
            document.write("null is greater than 0");
        }
        else if(null < 0) {
            document.write("null is less than 0");
        }
        else if(null == 0){
            document.write("null is equal to 0");
        }
        else {
            document.write("It is a typical relationship");
        }
    </script>
</body>
</html>

출력 결과

It is a typical relationship

예제 2: >= 비교

다음 예제에서 null은 0보다 크지도 않고, 0과 같지도 않지만, 0보다 크거나 같다는 조건은 참(true)이 됩니다. 언뜻 들으면 매우 이상하게 느껴집니다. 수학적으로 두 수 a와 b가 있을 때, a가 b보다 작지 않다면 가능한 경우는 a가 b보다 크거나, a와 b가 같은 경우뿐이기 때문입니다.

그러나 JavaScript에서 null과 0의 관계는 이러한 수학적 직관을 따르지 않습니다. 이것이 바로 JavaScript를 다룰 때 주의해야 할 전형적인 사례입니다.

<html>
<body>
    <script>
        if(null > 0){
            document.write("null is greater than 0");
        }
        else if(null == 0){
            document.write("null is equal to 0");
        }
        else if(null >= 0) {
            document.write("null is greater than or equal to 0 ");
        }
    </script>
</body>
</html>

출력 결과

null is greater than or equal to 0

왜 이런 모순적인 결과가 나올까?

비밀은 JavaScript의 타입 강제 변환(type coercion) 규칙에 있습니다. 연산자 종류에 따라 null이 처리되는 방식이 다릅니다.

  • 관계 연산자(>, <, >=, <=): 비교 전에 피연산자가 숫자로 변환됩니다. Number(null)은 0이므로 null >= 0은 곧 0 >= 0과 같아지며, 결과는 true가 됩니다.
  • 동등 연산자(==): null은 숫자로 변환되지 않습니다. 추상적 동등 비교 규칙에 따라 null은 오직 undefined와만 같다고 판단되므로, null == 0은 false를 반환합니다.

즉, "null은 0보다 크지 않고 같지도 않지만 0보다 크거나 같다"는 모순처럼 보이는 현상은, 서로 다른 연산자가 null을 서로 다른 방식으로 변환·비교하기 때문에 발생하는 것입니다.

실무에서 주의할 점

이러한 암묵적 형변환은 예상치 못한 버그의 원인이 되기 쉽습니다. 안전한 코드를 위해 다음과 같은 습관을 권장합니다.

  • 값을 비교할 때는 타입까지 엄격히 검사하는 일치 연산자(===, !==)를 사용합니다.
  • null 여부를 확인할 때는 null === x 또는 x == null(null과 undefined를 동시에 검사) 패턴을 활용합니다.
  • 숫자 변환이 필요한 경우에는 Number(), parseInt() 등으로 명시적으로 변환한 뒤 비교합니다.

JavaScript의 타입 강제 변환 규칙을 이해하고 있으면, null과 0의 비교처럼 언뜻 기괴해 보이는 동작도 충분히 예측 가능한 결과임을 알 수 있습니다.