typeof nullの結果が「object」である理由を本当に知っていますか?

typeof nullの結果が「object」である理由を本当に知っていますか?

これまでのところ、ECMAScript標準で定義されているデータ型は、Undefined、Null、Number、Boolean、String、Symbol、BigInt、およびObjectの8つです。
変数のデータ型を判別するために、JavaScriptはtypeof演算子も提供します
データ型の値は、typeof演算子の操作後の出力値に対応します。

データの種類 結果
未定義 未定義 '未定義'
ヌル ヌル 「オブジェクト」
1、1.0、NaN、インフィニティ '数'
ブール値 真/偽 「ブール値」
ストリング ''、 'abc' 'ストリング'
シンボル Symbol()、Symbol( '123') 'シンボル'
BigInt 0n、1n 'bigint'
オブジェクト {}、[] 「オブジェクト」
オブジェクト 関数(){} '関数'

観察を通して、問題を見つけることができます-typeof演算子は、プリミティブ型の値nullをオブジェクトとして誤って判断します

typeof null === 'object'//true

これにより、typeof x === 'object'が発生し、xもnullになる可能性があります

この問題は、JavaScript 1の最初のバージョンにまでさかのぼることができますこのバージョンでは、単一の値がスタック内の32ビットストレージユニットを占有し、32ビットストレージユニットはタイプタグ(1〜3ビット)に分割できます。)そして実際のデータ、タイプラベルは下位ビットに格納され、5つのタイプに分けることができます。

(1)
window10計算機プログラマーモードからの画像
2示すように、0、1、2番目のビットがすべて0の場合、typeofはタイプをオブジェクト」と判断します。

(2)
window10計算機プログラマーモードからの画像
2示すように、0番目のビットが1の場合、typeofはタイプを「数値(整数)と判断します。

(3)
ここに画像の説明を挿入
2示すように、0番目と2番目のビットが両方とも0で、1番目のビットが1の場合、判定タイプのタイプは「数値(浮動小数点)」です。

(4)
ここに画像の説明を挿入
2示すように、0番目のビットと1番目のビットが両方とも0で、2番目のビットが1の場合、typeofはタイプを文字列」と判断します。

(5)
ここに画像の説明を挿入
2示すように、1番目と2番目のビットが両方とも1で、0番目のビットが0の場合、typeofは型をブール値」と判断します。

さらに、2つの特殊なケースがあります。
未定義:整数-2 ^ 30(整数の範囲外の数値)
null:0から31までの数字はすべて0(0、1、2番目のビットがすべて0場合、typeofが型をオブジェクト」と判断するという条件を満たすだけです。

次のコードは、この問題をよりよく示しています(ソース)。

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)) {
    
    
            type = JSTYPE_VOID;
        } else if (JSVAL_IS_OBJECT(v)) {
    
    
            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) 
                 : ops->call != 0)) {
    
     
                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;
    }

このため、typeof null === 'object'はtrueです。


  1. 現時点では、SymbolとBigIntがないため、これらは議論の対象外です。↩︎

  2. 写真はwindow10電卓のプログラマ・モードから来ています。↩︎ ↩︎ ↩︎ ↩︎ ↩︎

おすすめ

転載: blog.csdn.net/qq_35508835/article/details/108299244