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)
As shown in Figure 2 , when the 0th, 1st and 2nd digits are all 0, the typeof judgment type is'object ';
(2)
As shown in Figure 2 , when the 0th bit is 1, typeof judges the type to be'number (integer) ';
(3)
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)
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)
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.