typeof null 是 object是一个从js第一版就出先并且延续至今的bug,而且是无法修复的.
在js中有两种值是特殊的:
- undefined (JSVAL_VOID)是整数−(2^30)(数值在整数范围外)。
- null (JSVAL_NULL)是代码空指针。或者:一个对象类型标签加上一个为零的引用。
typeof null 被认为是对象:它检查了它的类型标签,类型标签说是“object”。
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)中,引擎首先检查值v 是否是undefined (VOID)。比较两个值是否相等。
#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID)
(2)是检查值是否有对象标签。如果它是可调用的(3)或者它的内部属性[[Class][]
将它标记为一个函数(4)那么’ v ‘就是一个函数。否则,它就是一个对象。这是’ typeof null '生成的结果。
接下来是检查数字,字符串和boolean。这里没有给null明确的检查,它可以由C的宏执行。