为什么 typeof null === ‘object‘ 到 2025 还在

为什么 typeof null 是 'object'

早期 JS 引擎用紧凑的内部表示:**对象类型的标记是 ​​0​​。 而 ​​null​​ 用 空指针 表示,在那套编码里标记也恰好是 ​​0​​**。​​typeof​​ 读到 ​​0​​,就返回了 ​​"object"​​。

如果你是靠搜索速成学的 JS,大概率早早踩过这个坑:

typeof null // "object"

    等等——null 表示“没有值”“空”,怎么会是 object?

    简答:历史遗留 bug,为了兼容被保留下来。长答:它很迷惑人,尤其坑初学者;当你需要区分“真对象”和 null 时,别单靠 typeof,用更清晰的检查方式。

    下面用直观示例 + 实战模式讲清楚原理、影响和写法。

    typeof 会返回什么

    typeof 是一元运算符,返回一个字符串表示值的类型标签。例如:

    typeof 123           // "number"
    typeof "hi"          // "string"
    typeof true          // "boolean"
    typeof undefined     // "undefined"
    typeof Symbol()      // "symbol"
    typeof 10n           // "bigint"
    typeof (() => {})    // "function"
    typeof {}            // "object"
    typeof []            // "object"
    typeof null          // "object"  // ← 这里出戏

    结论:你用 typeof x === "object" 判断“对象”时,会把 null 也算进去。

    它为什么会这样(历史原因)

    早期 JS 引擎用紧凑的内部表示:**对象类型的标记是 0。 而 null 用 空指针 表示,在那套编码里标记也恰好是 0**。typeof 读到 0,就返回了 "object"。

    等到规范与浏览器实现逐步固定,这个行为已经被大量网页依赖。改掉会大面积破坏线上站点,于是就被写进历史了。

    一句话:实现细节的 Bug,因为兼容性永久保留。

    这事为什么重要

    如果你只靠 typeof 来判断对象,会得出错误结论:

    function isObject(v) {
      return typeof v === "object";
    }
    
    isObject(null)   // true(错误期望)

    于是你以为能安全访问属性,结果:

    const v = null;
    // v.foo  // TypeError: Cannot read properties of null

    正确写法(生产可用)

    1) 明确检查 null
    value === null

      最直、最快、最不歧义。

      2) 同时判断“空值”(null 或 undefined)
      value == null  // 使用宽松等号:null 或 undefined 时为 true

        这里有意用 ==,因为它只在 null/undefined 上合并判断,简洁且惯用。

        3) 判断“可访问的对象”(非 null 的 object)
        value !== null && typeof value === "object"

          或封装:

          const isObject = v => v !== null && typeof v === "object";
            4) 判断“纯对象”(plain object,不含数组/日期等)
            function isPlainObject(v) {
              return Object.prototype.toString.call(v) === "[object Object]";
              // 或:v !== null && typeof v === "object" && !Array.isArray(v)
            }

              Object.prototype.toString 对区分 Array/Date/RegExp 等很稳。

              5) 需要深操作时,用现成工具

              深拷贝/合并等,不要手搓类型判断: 用 structuredClone、lodash.isPlainObject、_.cloneDeep、或现代库的成熟实现。

              示例与坑点

              数组等也是“object”
              Array.isArray([])                     // true
              typeof []                             // "object"
              Object.prototype.toString.call([])    // "[object Array]"
              
              typeof new Date()                     // "object"
              Object.prototype.toString.call(new Date()) // "[object Date]"

              所以 typeof 把 数组、日期、正则、null 都归到 "object" ——你若要具体类型,typeof 不够用。

              函数有特殊标签
              typeof function(){}   // "function"
              typeof (() => {})     // "function"

              函数本质是对象,但 typeof 会给出特殊结果"function"。

              推荐实践模式
              • 意图明确:要找 null → value === null;要找“空值” → value == null。
              • 访问前守卫:
              if (value !== null && typeof value === "object") {
                // 再读属性;若关心具体对象种类,再额外判断(如 Array.isArray)
              }

              (注意 if (obj && obj.prop) 会把 0/''/false 也当 falsey,可能不符合意图)

              • 抽成工具函数:在代码库里统一用 isObject、isPlainObject 等。
              • TypeScript:类型系统能避免许多静态错误;但运行时仍需校验外部输入。
              • 校验外部数据:API/用户输入用 zod / ajv / io-ts 做结构校验,别指望 typeof。
              速查表(Cheat Sheet)
              // 是 null 吗?
              value === null
              
              // 是 null 或 undefined 吗?
              value == null
              
              // 是对象且不是 null 吗?
              value !== null && typeof value === "object"
              
              // 是数组吗?
              Array.isArray(value)
              
              // 是“纯对象”(非数组/日期/正则/…)吗?
              Object.prototype.toString.call(value) === "[object Object]"
              
              // 访问前守卫(对对象):
              if (value !== null && typeof value === "object") {
                // 这里再读属性(必要时再区分具体类型)
              }

                typeof null === "object" 是 JS 里那种学一次就忘不掉的小地雷。 它存在不是因为“合理”,而是因为“历史兼容”。

                对你来说最重要的:别被它再坑到。 写明确的判断、用小工具函数、对外部数据做校验。 这样既能避免阴沟里翻船,也能让代码意图清晰、方便新人上手。

                AI大模型学习福利

                作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

                一、全套AGI大模型学习路线

                AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

                因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

                二、640套AI大模型报告合集

                这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

                因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

                三、AI大模型经典PDF籍

                随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。


                因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

                四、AI大模型商业化落地方案

                因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

                作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量

                评论
                添加红包

                请填写红包祝福语或标题

                红包个数最小为10个

                红包金额最低5元

                当前余额3.43前往充值 >
                需支付:10.00
                成就一亿技术人!
                领取后你会自动成为博主和红包主的粉丝 规则
                hope_wisdom
                发出的红包
                实付
                使用余额支付
                点击重新获取
                扫码支付
                钱包余额 0

                抵扣说明:

                1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                余额充值