花费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)

相关推荐
ai超级个体10 分钟前
别再吹牛了,100% Vibe Coding 存在无法自洽的逻辑漏洞!
前端·ai·ai编程·vibe coding
Mike_jia33 分钟前
🎓 OpenMAIC 终极指南:清华开源的多智能体 AI 互动课堂平台
前端
踩着两条虫37 分钟前
告别低代码“黑盒”!VTJ.PRO 2.0:用AI与自由重塑Vue3开发
前端·低代码·ai编程
OpenTiny社区43 分钟前
WebAgent :基于 MCP 协议打造的智能应用“超级路由器”
前端·agent·mcp
dweizhao1 小时前
别再用 Figma 画线框图了,Google 这款免费工具直接出 UI 稿
前端
han_1 小时前
JavaScript设计模式(五):装饰者模式实现与应用
前端·javascript·设计模式
ProgramHelpOa2 小时前
Amazon SDE Intern OA 2026 最新复盘|70分钟两题 Medium-Hard
java·前端·javascript
smchaopiao2 小时前
如何用CSS和JS搞定全屏图片展示
前端·javascript·css
酉鬼女又兒2 小时前
零基础快速入门前端CSS Transform 与动画核心知识点及蓝桥杯 Web 应用开发考点解析(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·css·职场和发展·蓝桥杯·html
山川行2 小时前
Python快速闯关8:内置函数
java·开发语言·前端·笔记·python·学习·visual studio