在 JavaScript 中,typeof null 返回的是 "object",这是一个历史遗留的 bug。虽然它看起来令人困惑,但背后其实有其底层实现的原因。
本文将从以下几个方面系统讲解:
typeof null的结果;- 其背后的历史原因(早期 JavaScript 的值存储机制);
- 为什么这个错误没有被修复;
- 实际开发中的正确判断方式;
- 相关知识拓展。
一、现象:typeof null 的结果是 "object"
console.log(typeof null); // "object"
这与我们对 null 的理解不符 —— 它是一个原始值,表示“空对象指针”,并不是一个真正的对象。
这是 JavaScript 中最著名的类型判断“bug”之一。
二、根本原因:JavaScript 初版的值存储机制
JavaScript 最初版本(由 Brendan Eich 在 Netscape Navigator 开发)中,所有的值都被存储为 32 位的单元(tagged pointers),每个单元包含两个部分:
| 部分 | 描述 |
|---|---|
| 类型标签(Type Tag) | 低位的 1~3 bits 表示数据类型 |
| 值(Value) | 剩下的位数用于存储实际的数据 |
类型标签设计如下:
| 标签(二进制) | 数据类型 |
|---|---|
000 | object |
001 | int |
010 | double |
100 | string |
110 | boolean |
特殊值:
undefined被表示为一个超出整数范围的数字(例如-2^30);null被表示为机器码中的 NULL 指针(全为 0),因此它的类型标签也是000,和对象相同。
这就是为什么 typeof null === "object" 的根本原因:在底层实现中,null 的类型标签和对象一样。
三、为什么不修复这个 bug?
尽管这是一个明显的错误,但它已经被广泛接受并写入了成千上万的代码库中。
ECMAScript 委员会曾考虑修复这个问题,但由于以下原因最终选择保留原样:
✅ 兼容性问题:
- 太多现有代码依赖
typeof null === "object"; - 修改会导致大量项目出错;
✅ 历史包袱:
- 这个 bug 已经存在超过 25 年;
- 是 JavaScript 发展过程中的一部分;
📌 所以,即使我们知道这是一个 bug,也只能接受它是 JavaScript 的一部分。
四、如何正确判断 null?
既然 typeof 不可靠,我们可以使用严格相等操作符来判断:
function isNull(value) {
return value === null;
}
console.log(isNull(null)); // true
console.log(isNull(undefined));// false
console.log(isNull({})); // false
更全面的类型判断方法:
function getType(value) {
if (value === null) return 'null';
if (Array.isArray(value)) return 'array';
return typeof value;
}
五、一句话总结
typeof null === "object"是 JavaScript 初期设计时的一个历史 bug,源于底层值的存储机制。虽然它已被广泛认知为错误,但由于兼容性和历史原因并未被修复。在实际开发中应使用=== null来准确判断null。
💡 进阶建议
- 学习 TypeScript,通过类型系统提前避免
null和undefined的问题; - 使用
Optional Chaining(?.)和Nullish Coalescing(??)提高代码健壮性; - 理解
Object.prototype.toString.call(null)可以返回[object Null],比typeof更准确; - 阅读 V8 引擎源码,了解现代 JS 引擎如何处理原始值与对象;