花费28800秒,我终于知道了 typeof null 为 object 的原理

1.背景

我之前一直知道 typeof null 为 object ,但是一直没深究为什么?在查阅了相关的文档,汇总为以下文档

2.汇总解释

我们先来看 《JavaScript高级程序设计》 里面是怎么说的吧?

Null 类型同样只有一个值,即特殊值 null。逻辑上讲,null 值表示一个空对象指针,这也是给 typeof 传一个 null 会返回 "object" 的原因

这里我们就可以解释通了,null 其实是一个 空对象指针 ,所以 typeof 会检测 nullobject

如果单纯是这样必然是不对的,是 空对象指针 就一定会被检测为 object 吗?

这其实就是一句总结,里面肯定有更加深层的原因,我看了一眼 ECMAScript 的文档,发现没有说这一点(可能是我没找到),倒是在 MDN 发现了解释

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"

我来简单解释一遍,对象类型 表示为 0null 在大部分机器上面都是 0x00...000 ,所以 null0 ,所以 nulltypeof 下 会被检测为 object

3.详细解释

这个解释已经能解答很多疑惑了,如果我们再往下面看一层呢?为什么对象类型为 0 ,null 为 0x00typeof 底层分析类型是通过什么手段?以及这部分源码是什么样子的?

其实 JavaScript 的数据类型其实是通过 数据标签 + 数据值 的形式存在的,下面就是常见的数据标签

数据标签 类型
000 object
1 int
010 double
100 string
110 boolean

在32位机器中,int 的 标签为 1 ,占了一位,那么后续的值为 2 ^ 30 ~2 ^ 30 - 1 (根据上图推算,现代JS早就改);其中 object 的标签为 000

这就是 JavaScript 的数据类型如何去做处理和区分的,当然还有2个特殊的值

  • undefined 源码标记为 JSVAL_VOID
  • null 源码标记为 JSVAL_NULL :是机器代码的 NULL****指针 。或者说,它是一个对象类型标记加上一个引用为零的组合,大部分机器都认定为 0x000

我们来看下面的 typeof 源码部分

  • 发现没有 显式的判断 null****值 的标记,只有 undefined,object,number,string,boolean 的判断
  • 再加上 null 在很多的机器中默认是 0x000 ,那么就会走 JSVAl_IS_OBJECT(v) 的逻辑,被认定为 object 类型
c 复制代码
// 这是一个宏,它指定了函数的返回类型为 JSType,并且声明该函数是一个公共API  
JS_PUBLIC_API(JSType)  
JS_TypeOfValue(JSContext *cx, jsval v) {  
    JSType type = JSTYPE_VOID;  
    JSObject *obj;  
    JSObjectOps *ops;  
    JSClass *clasp;  
     
    // 这是一个宏,用于检查传入的 JSContext 是否有效  
    CHECK_REQUEST(cx);  
     
    if (JSVAL_IS_VOID(v)) {  
        type = JSTYPE_VOID;  
    } else if (JSVAL_IS_OBJECT(v)) {  
        // 如果 v 是对象类型,则检查它是否是函数对象,如果是函数对象则将 type 设置为 JSTYPE_FUNCTION  
        // 否则将其设置为 JSTYPE_OBJECT  
        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) : ops->call != 0)) {   
            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;  
}

V8 Blog 对于 typeof null 为 object 的解释。我来简单解释一下:V8 Blog 认为 null 表示 no object value,所以输出 object 没问题

当然这有一股王婆卖瓜,自卖自夸的感觉了,毕竟是 JavaScript 最初设计的问题

4.总结

到这里继续深究下去已经没必要了,就是最初设计的缺陷导致的,当然这次的查询告诉我们对于高级语言的设计并不一定都是对的,如果想深究,也能看到 JavaScript 很多不合理的地方

参考文章

javascript - Why is typeof null "object"? - Stack Overflow

The story of a V8 performance cliff in React · V8

typeof - JavaScript | MDN (mozilla.org)

The history of "typeof null" (2ality.com)

typeof 与 Javascript 类型源码分析 - 知乎 (zhihu.com)

相关推荐
linweidong4 小时前
C++ 模块化编程(Modules)在大规模系统中的实践难点?
linux·前端·c++
leobertlan7 小时前
2025年终总结
前端·后端·程序员
子兮曰8 小时前
OpenClaw架构揭秘:178k stars的个人AI助手如何用Gateway模式统一控制12+通讯频道
前端·javascript·github
百锦再8 小时前
Reactive编程入门:Project Reactor 深度指南
前端·javascript·python·react.js·django·前端框架·reactjs
莲华君8 小时前
React快速上手:从零到项目实战
前端·reactjs教程
百锦再8 小时前
React编程高级主题:测试代码
android·前端·javascript·react.js·前端框架·reactjs
易安说AI9 小时前
Ralph Loop 让Claude无止尽干活的牛马...
前端·后端
失忆爆表症10 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
小迷糊的学习记录10 小时前
Vuex 与 pinia
前端·javascript·vue.js
发现一只大呆瓜11 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试