为什么 typeof null === object
JavaScript has its charming quirks, and one of them is the typeof
operator, which determines the type of a value.
JavaScript 有其迷人的怪癖,其中之一就是 typeof
运算符,它用于确定值的类型。
Expected behavior:
预期行为:
typeof 100 //number
typeof "string" //string
typeof {} //object
typeof Symbol //function
typeof undefinedVariable // undefined
And here’s our favorite, which is today’s star of this article:
接下来是我们最喜欢的,也是今天文章的主角:
JavaScript, like other programming languages, has types that can be divided into “primitive” - those that return a single value (null, undefined, boolean, symbol, bigint, string
) and “object” types, which have a complex structure. Simply put - for example, boolean
in JavaScript is something that isn’t a very complicated structure, as it returns only one value: true
or false
.
JavaScript 与其他编程语言一样,类型可以分为“原始”——返回单个值的类型(null, undefined, boolean, symbol, bigint, string
)和“对象”类型,后者具有复杂结构。简单来说——例如,JavaScript 中的 boolean
并不是一个复杂的结构,因为它只返回一个值:true
或 false
。
For instance, in the modern Firefox implementation, a technique called “pointer tagging” is used, where a 64-bit value encodes the type and value or address on the heap. Let’s look at how booleans are handled in this implementation:
例如,在现代 Firefox 实现中,使用了一种称为“pointer tagging”的技术,其中 64 位值编码了类型以及堆上的值或地址。让我们看看在这种实现中布尔值是如何处理的:
Keyword | Tag | Payload |
---|---|---|
false |
JSVAL_TAG_BOOLEAN (0xFFFE*) |
0x000000000000 |
true |
JSVAL_TAG_BOOLEAN (0xFFFE*) |
0x000000000001 |
关键字 | 标签 | 负载 |
---|---|---|
false |
JSVAL_TAG_BOOLEAN (0xFFFE*) |
0x000000000000 |
true |
JSVAL_TAG_BOOLEAN (0xFFFE*) |
0x000000000001 |
You can notice that the high bits are responsible for defining the data type, and the low bits for the payload or the address of the allocated object on the heap. So in this case, our true/false
is represented in binary as 1/0
.
你可以注意到,高位负责定义数据类型,而低位负责有效载荷或堆上已分配对象的地址。因此,在这种情况下,我们的 true/false
在二进制中被表示为 1/0
。
You’re probably wondering what this has to do with typeof null
returning object
instead of null.
你可能在想,这与 typeof null
返回 object
而不是 null 有什么关系。
To understand this, we need to go back 30 years to the original JavaScri...