null === null, undefined === undefined, NaN === NaN

    728x90
    반응형
    SMALL

     

     

    null === null, undefined === undefined는 되는데 왜 NaN ===NaN은 안돼?
     

    답변: NaN은 "특정 값"이 아니라 "숫자가 아닌 상태"

    NaN = Not a Number

    // NaN이 생성되는 경우
    0 / 0;              // NaN
    Math.sqrt(-1);      // NaN
    parseInt('hello');  // NaN
    Number('abc');      // NaN
    undefined + 1;      // NaN
    
    // 각각 다른 연산이지만 모두 NaN
    // 하지만 "같은 NaN"이 아님!

    핵심: NaN은 하나의 값이 아니라 "숫자가 아닌 모든 것"을 나타냄

     

    null vs undefined vs NaN

    null과 undefined는 "특정 값"

    // null = "값이 없음"을 나타내는 특정한 값
    const a = null;
    const b = null;
    
    a === b;  // true (같은 "값 없음")
    
    // undefined = "정의되지 않음"을 나타내는 특정한 값
    let x;
    let y;
    
    x === y;  // true (같은 "정의 안 됨")

    특징:

    • null은 1개의 값 (null)
    • undefined는 1개의 값 (undefined)
    • 비교 가능 ✅

     

    NaN은 "상태"

    // NaN = "숫자가 아닌 것"을 나타내는 상태
    const result1 = 0 / 0;        // NaN (0을 0으로 나눔)
    const result2 = Math.sqrt(-1); // NaN (음수의 제곱근)
    const result3 = parseInt('abc'); // NaN (숫자 변환 실패)
    
    // 모두 NaN이지만 원인이 다름
    result1 === result2;  // false
    result2 === result3;  // false
    NaN === NaN;          // false
    
    // "숫자가 아닌 것"들은 서로 같지 않음!

    특징:

    • NaN은 무수히 많은 "잘못된 계산 결과"들
    • 각각 다른 이유로 생성됨
    • 비교 불가능 ❌

     

     

    null과 undefined는 '공유된 표지판' (싱글톤)

    자바스크립트 엔진(예: 크롬의 V8)이 처음 시동을 걸 때, 메모리 한구석에 **null**과 **undefined**라는 **유일한 값(객체)**을 미리 딱 만들어 둡니다. (이걸 기술적으로는 'Sentinel Value' 또는 'Root'라고 합니다.)

    • 변수 할당 시: let a = null;이라고 하면, 메모리에 새로운 null을 만드는 게 아니라, 이미 만들어져 있는 그 유일한 null의 주소를 a에게 쥐여줍니다.
    • 비교 시: null === null은 결국 **"너랑 나랑 가리키는 주소가 같니?"**를 묻는 것과 같습니다. 둘 다 엔진이 처음에 만든 '그 놈'을 가리키고 있으니 당연히 **true**입니다.

     

    그럼 NaN은? (메모리가 아니라 '규칙'의 문제)

    여기서 NaN이 특이한 점이 드러납니다. 사실 컴퓨터 내부(메모리 비트 패턴)로 깊이 들어가면 NaN도 어떤 특정한 비트 값을 가지고 있습니다. 메모리상에서 똑같은 NaN 비트 패턴을 가질 수도 있죠.

    하지만! 자바스크립트(IEEE 754 표준)는 NaN을 만났을 때 메모리 주소를 비교하는 절차를 무시하고 무조건 false를 뱉도록 '법'으로 정해놨습니다.

    • null: "주소가 같으니 같다." (메모리 참조 비교 성공)
    • NaN: "주소고 뭐고, 넌 NaN이니까 무조건 탈락." (비교 로직에서 예외 처리)

     

     

    위에서 null, undefined 가 싱글톤이라고 했는데?

    null은 인스턴스인가요?
    A. 엄밀히 말하면 자바스크립트 문법상 null은 객체의 인스턴스가 아니라 **'원시 값(Primitive Value)'**입니다.
    하지만 메모리 효율을 위해 자바스크립트 엔진 내부적으로는 마치 **'싱글톤(하나뿐인 객체)'**처럼 관리됩니다.
    프로그램이 시작될 때 메모리에 딱 한 번 할당되고, 우리가 null을 사용할 때마다 그 메모리 주소를 계속 재사용하기 때문입니다.
    그래서 null === null이 성립하는 것입니다.

     

    **"클래스(설계도)는 있지만, 실제 제품(인스턴스)은 딱 하나만 만들어서 계속 재활용하는 것"**이 바로 싱글톤 패턴의 핵심입니다.

    이해를 돕기 위해 일반적인 클래스싱글톤 클래스가 어떻게 다른지, 그리고 이게 **null**과 어떻게 연결되는지 정리해 드릴게요.

     

    일반 클래스 vs 싱글톤 클래스

    A. 일반적인 클래스 (붕어빵 틀)

    보통은 new를 할 때마다 새로운 메모리를 써서 새 객체를 만듭니다.

    class Dog { ... }
    
    const dog1 = new Dog(); // 🐶 멍멍이 1호 탄생 (메모리 100번지)
    const dog2 = new Dog(); // 🐶 멍멍이 2호 탄생 (메모리 200번지)
    
    console.log(dog1 === dog2); // false (서로 다른 개니까)
    

    B. 싱글톤 패턴 (공용 프린터)

    싱글톤으로 만들면, 생성자(Constructor)가 실행될 때 "이미 만들어둔 게 있나?"를 먼저 검사합니다.

    • 첫 번째 호출: "없네? 하나 만들어서 저장해두고 이거 줄게."
    • 두 번째 호출: "아까 만든 거 있지? 그거 다시 가져가."
    class SchoolPrincipal {
      constructor() {
        // 1. 이미 만들어진 교장선생님이 있는지 확인
        if (SchoolPrincipal.instance) {
          return SchoolPrincipal.instance; // 있으면 그거 반환 (새로 안 만듦)
        }
        
        // 2. 없으면 내가 그 '유일한 존재'가 됨
        SchoolPrincipal.instance = this;
      }
    }
    
    const p1 = new SchoolPrincipal(); // 👨‍🏫 교장선생님 탄생 (메모리 500번지)
    const p2 = new SchoolPrincipal(); // 👨‍🏫 아까 그분 (메모리 500번지)
    
    console.log(p1 === p2); // true (완벽히 같은 존재)

     

     

    728x90
    반응형
    LIST

    댓글