Do you really know why the result of typeof null is'object'?

Do you really know why the result of typeof null is'object'?

So far, there are 8 data types defined in the ECMAScript standard, which are Undefined, Null, Number, Boolean, String, Symbol, BigInt, Object.
In order to determine the data type of the variable, JavaScript also provides the typeof operator .
The value in the data type corresponds to the output value after the operation of the typeof operator:

type of data value result
Undefined undefined ‘undefined’
Null null ‘object’
Number 1、1.0 、 NaN 、 Infinity ‘number’
Boolean true、false ‘boolean’
String ‘’ 、‘abc’ ‘string’
Symbol Symbol()、Symbol(‘123’) ‘symbol’
BigInt 0n 、 1n ‘bigint’
Object {}、[] ‘object’
Object function(){} ‘function’

Through observation, we can find a problem-the typeof operator incorrectly judges a primitive type value null as an object

typeof null === 'object'//true

This will cause typeof x ==='object', x may also be null

This problem can be traced back to the first version of JavaScript 1. In this version, a single value occupies a 32-bit storage unit in the stack, and the 32-bit storage unit can be divided into type tags ( 1-3 bits) ) And the actual data, the type label is stored in the lower bits, which can be divided into 5 types:

(1)
Picture from window10 calculator programmer mode
As shown in Figure 2 , when the 0th, 1st and 2nd digits are all 0, the typeof judgment type is'object ';

(2)
Picture from window10 calculator programmer mode
As shown in Figure 2 , when the 0th bit is 1, typeof judges the type to be'number (integer) ';

(3)
Insert picture description here
As shown in Figure 2 , when the 0th and 2nd bits are both 0, and the 1st bit is 1, the typeof judgment type is'number (floating point) ';

(4)
Insert picture description here
As shown in Figure 2 , when the 0th bit and the 1st bit are both 0, and the 2nd bit is 1, the typeof judges the type to be'string ';

(5)
Insert picture description here
As shown in Figure 2 , when the first and second bits are both 1, and the 0th bit is 0, typeof judges the type to be'boolean ';

In addition, there are two special cases:
undefined: integer −2^30 (number outside the range of integer)
null: digits 0 to 31 are all 0 (It just satisfies the condition that typeof judges the type to be'object ' when the 0th, 1st and 2nd bits are all 0)

The following code better illustrates this problem ( source ):

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;
    }

Because of this, typeof null ==='object' is true.


  1. At this time, there is no Symbol and BigInt, so they are not in the scope of discussion; ↩︎

  2. The picture comes from the programmer mode of the window10 calculator; ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

Guess you like

Origin blog.csdn.net/qq_35508835/article/details/108299244