为什么typeof null
的结果是Object
null是基本类型 而object 是引用类型 这样就会存在矛盾
我们从源码解析看这个问题 我们的JS 是 经过V8 引擎编译的 所以我们需要调试V8
安装工具 node版本要高
npm install -g jsvu
安装V8引擎
jsvu --os=win64 --engines=v8-debug
//os 根据自己的操作系统选择
切换到用户目录下面的.jsvu
通过以下命令生成字节码
v8-debug -e --print-bytecode --allow-natives-syntax "var x = xxxx"
根据生成的字节码得出的结论
数据类型 | 机器码标识对象 |
(Object) | 000 |
整数 | 1 |
浮点数 | 010 |
字符串 | 100 |
布尔 | 110 |
| 全为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)) { // (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;
}
在判断数据类型时,是根据机器码低位标识来判断的,而null
的机器码标识为全0
,而对象的机器码低位标识为000
。所以typeof null
的结果被误判为Object