typeof(null)는 왜 "object"입니까?

8061 단어

배경.👀


만약 당신이 매일 '자바스크립트' 를 처리하는 개발자라면, 최소한 조작부호의 유형을 들은 적이 있을 것이다.우리가 알고 있는 바와 같이, 'typeof' 연산자의 문법 뒤에는 'operand' 가 따른다. 이것은 그 유형의 'Object' 또는 'primitive' 를 되돌려야 한다는 표현식이다.
이 정의에 따라'typeof(ANY PRIMITIVE TYPE)'는 이 기원 유형을 문자열로 되돌려야 하며, 기원 유형을 제외한 모든 유형은'object'로 여겨야 한다.
지금까지 JavaScript는 이 언어에서 7가지 기본 데이터 유형을 가지고 있습니다.
  • string
  • number
  • bigint
  • boolean
  • undefined
  • symbol
  • null
  • console에서 다음 코드를 실행하여 각각'Primitive'유형에 대해 무엇을 되돌려 주는지 살펴보겠습니다.
    typeof "Sourav"    // "string"
    typeof 1    // "number"
    typeof 1n    // "bigint"
    typeof true    // "boolean"
    typeof undefined    // "undefined"
    typeof Symbol('Debnath')    // "symbol"
    typeof null    // "object"
    
    
    잠깐만...뭐?왜 null의 유형은'object'이고 그 유형은'null'입니까?우리는'신성'이 진리의 유일한 근원이라고 생각하는데 무슨 일이 일어났습니까?

    이것이 바로 이 블로그의 전체 내용이다!우리는 함께 원인을 탐색하여
    시작!

    왜 그랬어요?🤷‍♂️


    분명히 이것은 당신들 대다수가 생각하고 있는 첫 번째 문제일 것이다.
    JavaScript 신(예, [Brendan Eich])https://disqus.com/by/brendaneich/) 🙏) 그는 고의로 이렇게 했습니까?물론 아니다. 그가 새로운 언어를 디자인한 시간대(10일)를 감안하면 우리는 더 이상 요구할 수 없다!
    임무를 서둘러 수행하거나 교부할 수 있는 성과를 교부할 때 코드에 오류가 발생할 수 있습니다.현대에 우리는 소프트웨어 개발 모델을 따른다. 이런 모델에서 우리는 전문적인 QA 단계를 가지는데 이것은 1995-1996년의 Netscape Communications에 존재하지 않는다.
    JavaScript가 아닌 [LiveScript](https://www.youtube.com/watch?v=v2ifWcnQs6M) - 그것은 다른 날의 토론이다!

    JavaScript 엔진 이전 버전의 소스 코드와 "필요한 악성"에 대한 설명😈


    이전 릴리즈에서는 값이 32비트 셀에 저장되었으며 작은 유형 태그(1-3비트)와 값의 실제 데이터로 구성되어 있습니다.형식 탭은 단원의 낮은 위치에 저장됩니다.그 중 다섯 가지가 있다.
  • 000: 대상.데이터는 대상에 대한 인용이다.
  • 1:int. 데이터는 31자리 기호 정수입니다.
  • 010:두 배.데이터는 이중 부동점수에 대한 인용이다.
  • 100: 문자열.데이터는 문자열에 대한 인용입니다.
  • 110: 부울 값.데이터는 부울 값이다.
  • 즉, 가장 낮은 자리는 한 자리이고, 그 다음에 유형 표시는 한 자리만 길다는 것이다.또는 0이면 유형 라벨의 길이는 세 자리이고 네 가지 유형에 두 개의 추가 위치를 제공합니다.
    특별한 가치가 있다.

    null (JSVAL_NULL) was the machine code NULL pointer. Or: an object type tag plus a reference that is zero.


    ** 96년 Spider Monkey에서 사용된 클래식 자바스크립트 소스 코드: @evipies:https://twitter.com/evilpies/
        JS_PUBLIC_API(JSType)
        JS_TypeOfValue(JSContext *cx, jsval v)
        {
            JSType type = JSTYPE_VOID;
            JSObject *obj;
            JSObjectOps *ops;
            JSClass *clasp;
    
            CHECK_REQUEST(cx);
            if (JSVAL_IS_VOID(v)) {  // (1)
                type = JSTYPE_VOID;
            } else if (JSVAL_IS_OBJECT(v)) {  // (2)
                obj = JSVAL_TO_OBJECT(v);
                if (obj &&
                    (ops = obj->map->ops,
                     ops == &js_ObjectOps
                     ? (clasp = OBJ_GET_CLASS(cx, obj),
                        clasp->call || clasp == &js_FunctionClass) // (3,4)
                     : ops->call != 0)) {  // (3)
                    type = JSTYPE_FUNCTION;
                } else {
                    type = JSTYPE_OBJECT;
                }
            } else if (JSVAL_IS_NUMBER(v)) {
                type = JSTYPE_NUMBER;
            } else if (JSVAL_IS_STRING(v)) {
                type = JSTYPE_STRING;
            } else if (JSVAL_IS_BOOLEAN(v)) {
                type = JSTYPE_BOOLEAN;
            }
            return type;
        }
    
  • 이 코드의 첫 번째 검사(1)는 C 매크로에 의해 수행됩니다VOID (undefined).
  • #define JSVAL_IS_VOID(v)  ((v) == JSVAL_VOID)
    
  • 다음 검사(2)는 이 값에 표시가 있는지 여부object입니다.현재 null 에서 형식 탭을 검사했습니다. 형식 탭에 'object' 라고 쓰여 있고 else if 로 들어갔습니다.
  • 다른 호출 가능한 (3)이나 내부 속성 [[[Class]]이 함수(4)로 표시하면 v는 함수입니다.그렇지 않으면, 그것은 하나의 대상이다.typeof null에서 생성된 결과입니다.
  • 이외에 우리는 심지어 유형null에 대해 단독 검사를 하지 않았다. 이것은 VOID과 유사한 C宏을 통해 쉽게 실현될 수 있지만 앞에서 말한 바와 같이
  • When you perform tasks or deliver your deliverables in a hurry, it is expected that your code might be shipped with bug(s).


    이것은 단지 다른 문제일 뿐이다. 만약 우리가 이 문제를 해결한다면🚒


    **당신은 할 수 있지만 당신은 **해서는 안 된다
    ES5의 권장 사항은 다음과 같습니다.1 복구typeof 운영자는 V8의 harmony version 아래 실시되었으나 결국 많은 기존 사이트를 파괴했다. 이 제안은 거절당했다.

    In the spirit of One JavaScript this is not feasible.


    오늘 엔진 뚜껑 밑에 뭐가 있어요.🕵️


    일은 이미 CPP까지 발전했고 오늘의 코드는 매우 간단하다. 이미 알려진 버그는typeof null이다.JavaScript가 제안 토론에서 말했듯이

    "I think it is too late to fix typeof. The change proposed for typeof null will break existing code."


    Mozilla의 CPP 해석기에서의 실현searchfox을 살펴보겠습니다.
    JSType js::TypeOfValue(const Value& v) {
      switch (v.type()) {
        case ValueType::Double:
        case ValueType::Int32:
          return JSTYPE_NUMBER;
        case ValueType::String:
          return JSTYPE_STRING;
        case ValueType::Null: // 😈 😈 😈
          return JSTYPE_OBJECT; // 😈 😈 😈
        case ValueType::Undefined:
          return JSTYPE_UNDEFINED;
        case ValueType::Object:
          return TypeOfObject(&v.toObject());
        case ValueType::Boolean:
          return JSTYPE_BOOLEAN;
        case ValueType::BigInt:
          return JSTYPE_BIGINT;
        case ValueType::Symbol:
          return JSTYPE_SYMBOL;
        case ValueType::Magic:
        case ValueType::PrivateGCThing:
          break;
      }
    
      ReportBadValueTypeAndCrash(v);
    }
    
    그중typeof은 관찰할 수 있는 cpp 매거here:
    /* Result of typeof operator enumeration. */
    enum JSType {
      JSTYPE_UNDEFINED, /* undefined */
      JSTYPE_OBJECT,    /* object */
      JSTYPE_FUNCTION,  /* function */
      JSTYPE_STRING,    /* string */
      JSTYPE_NUMBER,    /* number */
      JSTYPE_BOOLEAN,   /* boolean */
      JSTYPE_NULL,      /* null */
      JSTYPE_SYMBOL,    /* symbol */
      JSTYPE_BIGINT,    /* BigInt */
      JSTYPE_LIMIT
    };
    

    결론✏️


    Below the surface of the machine, the program moves. Without effort, it expands and contracts. In great harmony, electrons scatter and regroup. The forms on the monitor are but ripples on the water. The essence stays invisibly below." - Master Yuan-Ma, The Book of Programming


    기능이나 제품을 개발할 때, 우리는 매일 많은 일을 처리해야 하지만, 우리는 실제로 우리가 상세하게 쓴 줄을 탐구하지 않고, 일이 발생한 원인을 찾지 못할 수도 있다.이 블로그는 바로 이러한 이론적 탐구이다😇
    이제 모든 C와 CPP에 이어 우리의 생각을 JS로 가져갑시다!JSTYPE_OBJECT버그가 아니냐고 물어볼지도 몰라요.
    답은: 아니오, 버그가 아닙니다.
    수조는 기원이 아니기 때문에 대상이다!날짜도 마찬가지다. '원시 목록' 에 없는 모든 것이 그렇다.
    null 같지 않아, 그들이 말한 것은 사실이야!

    좋은 웹페이지 즐겨찾기