不同的对象在底层都表示为二进制, 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0, 自然前三位也是 0, 所以执行 typeof null时会返回“object”。
javascript 中的 null:既是对象,又不是对象
typeof null === 'object'; // true
null instanceof Object // false
而
null instanceof null // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
底层二进制使用低位表示变量的类型信息
- 000:对象
- 1:整数
- 010:浮点数
- 100:字符串
- 110:布尔
有 2 个值比较特殊:
- undefined:用 - (−2^30)表示。
- null:对应机器码的 NULL 指针,一般是全零。
在第一版的 javascript 实现中,判断类型的代码是这么写的:
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;
}
(1):判断是否为 undefined
(2):如果不是 undefined,判断是否为对象
(3):如果不是对象,判断是否为数字
(4):。。。
这样一来,null 就出了一个 bug。根据 type tags 信息,低位是 000,因此 null 被判断成了一个对象。这就是为什么 typeof null 的返回值是 object。
这是 JavaScript 最初实现的一个 bug,目前的 JavaScript 引擎已经不这么去实现了,但是这个 bug 却一直流传了下来。至于对象的内部表示,不同的 JavaScript 引擎实现起来都是不一样的。
V8引擎是如何知道js数据类型的?
不同的对象在底层都表示为二进制, 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0, 自然前三位也是 0, 所以执行 typeof null时会返回“object”。
javascript 中的 null:既是对象,又不是对象
而
底层二进制使用低位表示变量的类型信息
有 2 个值比较特殊:
在第一版的 javascript 实现中,判断类型的代码是这么写的:
(1):判断是否为 undefined
(2):如果不是 undefined,判断是否为对象
(3):如果不是对象,判断是否为数字
(4):。。。
这样一来,null 就出了一个 bug。根据 type tags 信息,低位是 000,因此 null 被判断成了一个对象。这就是为什么 typeof null 的返回值是 object。
这是 JavaScript 最初实现的一个 bug,目前的 JavaScript 引擎已经不这么去实现了,但是这个 bug 却一直流传了下来。至于对象的内部表示,不同的 JavaScript 引擎实现起来都是不一样的。
V8引擎是如何知道js数据类型的?