23
Why typeof(null) is "object"?
typeof "Sourav" // "string"
typeof 1 // "number"
typeof 1n // "bigint"
typeof true // "boolean"
typeof undefined // "undefined"
typeof Symbol('Debnath') // "symbol"
typeof null // "object"
null
is of type "object" when it should be of type "null"? What happened to the definition which we were considering 'holy' and as the single source of truth? 
null (JSVAL_NULL) was the machine code NULL pointer. Or: an object type tag plus a reference that is zero.
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;
}
VOID (undefined)
check which is performed by a C macro:
#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID)
The next check (2) is whether the value has an object
tag. Now for null
, It examined its type tag and the type tag said “object” and it went inside the else if
.
If it additionally is either callable (3) or its internal property [[Class]] marks it as a function (4) then v is a function. Otherwise, it is an object. This is the result that is produced by typeof null.
On top of that, we do not even have a separate check for type null
, which was easy to implement by a C macro similar to VOID
but as I described above,
When you perform tasks or deliver your deliverables in a hurry, it is expected that your code might be shipped with bug(s).
typeof
operator and it was implemented under the harmony version in V8 but it ended up breaking a lot of existing sites and this proposal had been rejected, described as,In the spirit of One JavaScript this is not feasible.
CPP
and the code present today is pretty straight forward with the known bug of typeof null
; as Mr. JavaScript said in one of the proposal discussions,"I think it is too late to fix typeof. The change proposed for typeof null will break existing code."
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);
}
/* 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
typeof([]) === "object"
a bug?