【问题标题】:Why is typeof null "object"?为什么typeof null“对象”?
【发布时间】:2013-09-15 02:02:55
【问题描述】:

我正在阅读“面向 Web 开发人员的专业 Javascript”第 4 章,它告诉我五种类型的原语是:未定义、空值、布尔值、数字和字符串。

如果null 是原语,为什么typeof(null) 返回"object"

这是否意味着null 是通过引用传递的(我假设这里所有的对象都是通过引用传递的),因此它不是原始的?

【问题讨论】:

  • 答案:因为规范是这样说的。这通常被认为是一个错误。
  • 注意,typeof 是一个操作符,而不是一个函数(事实上你可以省略它后面的括号),所以在这里讨论通过引用传递是没有意义的。 “JavaScript: The Good Parts”一书实际上在附录 A 题为“糟糕的部分”的 A.6 节中提到了 typeof null === 'object'。
  • 我想我想读《糟糕的部分》哈哈
  • 大错特错,深不可测! :)
  • 那么我们应该使用什么来代替 typeof 来检查变量所持有的值的类型呢?我很想知道它之间是什么(布尔值、字符串、数字、数组、对象、函数、符号、null、未定义、NaN)

标签: javascript primitive


【解决方案1】:

来自the MDN page about the behaviour of the typeof operator

null

// 这从 JavaScript 开始就存在
typeof null === '对象';

在 JavaScript 的第一个实现中,JavaScript 值表示为类型标记和值。对象的类型标记为 0。null 表示为 NULL 指针(在大多数平台中为 0x00)。因此,null 有 0 作为类型标记,因此“对象”typeof 返回值。 (reference)

提出了针对 ECMAScript 的修复(通过选择加入),但 was rejected。这将导致typeof null === 'null'

【讨论】:

  • 很遗憾这个改动至少没有进入严格模式……
  • 人们一直在利用这个怪癖,如果没有被拒绝,很多代码都必须更改,我猜
  • 对于少数想要改变代码的活着的人来说,这比其他开发人员在剩下的时间里必须学习它更有意义。仅仅因为一个人还不存在,并不一定意味着他们不重要,这只意味着他们没有防御能力。
  • 不明白为什么人们会将此用作空检查。它没有直观的意义,那么他们为什么要使用它呢?由于编码错误,现在无法添加更改。
【解决方案2】:

如果null 是原语,为什么typeof(null) 返回"object"

因为the spec says so

11.4.3typeof 运算符

产生式 UnaryExpression : typeof UnaryExpression 评估如下:

  1. val 为计算 UnaryExpression 的结果。
  2. 如果Type(val) 是Reference,那么
    一种。如果IsUnresolvableReference(val) 为true,则返回“undefined”。
    湾。设 valGetValue(val)。
  3. 根据表 20 返回由Type(val) 确定的字符串。

【讨论】:

  • @peter typeof 没有告诉你是否可以在某事上调用方法。
  • 据我所知,您可以在 nullundefined 以外的任何对象上调用方法。
  • @peter 您不能在字符串原语上调用方法,但幸运的是,字符串原语(以及数字原语和布尔原语)在字符串、数字和布尔包装器中隐式自动“自动装箱”使用带有属性引用运算符(.[ ])的原语之一。
【解决方案3】:

正如已经指出的那样,规范是这样说的。但是由于 JavaScript 的实现早于 ECMAScript 规范的编写,并且规范小心翼翼地不纠正初始实现的弱点,所以仍然存在一个合理的问题,即为什么它首先会以这种方式完成。道格拉斯·克罗克福德calls it a mistake。基罗风险thinks it kinda sorta makes sense

这背后的原因是nullundefined 相比,经常(现在仍然)在对象出现的地方使用。换句话说,null 通常用于表示对对象的空引用。当 Brendan Eich 创建 JavaScript 时,他遵循相同的范例,并且(可以说)返回“对象”是有意义的。事实上,ECMAScript 规范将null 定义为表示有意不存在任何对象值的原始值(ECMA-262, 11.4.11)。

【讨论】:

  • 由于我现在找不到视频,我将只为好奇的人发布此视频,没有任何参考:Crockford 解释了解析 null 类型的零值如何指向types 数组,所以这是一个明显的开发错误,微软人员在为他们的浏览器反编译和重新编译 JS 时意外传播了这个错误
【解决方案4】:

来自书YDKJS

这是 JS 中一个长期存在的错误,但很可能永远不会发生 等待修复。 Web 上太多的代码依赖于错误,因此 修复它会导致更多的错误!

【讨论】:

  • 不要相信一切都写在书中。我真的很喜欢那本书,但是,我不能认为这是一个错误,因为 JavaScript 的 ECMA 规范规定 null 的类型必须是对象。
  • @andreasonny83 This blog post 解释了为什么它是一个错误。规范声明typeof nullobject 的事实仅仅意味着规范选择将错误合并为规范的一部分。无论如何,这就是为什么我确实认为它是一个错误。 :)
  • 还有Brendan Eich explains 为什么是故意的。 typeof null === "object" 不是错误,而是必须适应 Java 互操作性的二阶效应。
【解决方案5】:

如果null 是原语,为什么typeof(null) 返回“object”?

简而言之:是ECMAScript中的bug,类型应该是null

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null

【讨论】:

  • 您的参考资料中没有任何地方表明这是一个错误。
  • 在规范中没有任何地方说 typeof 应该返回除“undefined”、“object”、“boolean”、“number”、“string”、“function”和“symbol”之外的任何内容( ECMAScript 2015)
【解决方案6】:

在 JavaScript 中,null 是“无”。它应该是不存在的东西。不幸的是,在 JavaScript 中,null 的数据类型是一个对象。你可以认为它是 JavaScript 中的一个错误,即 typeof null 是一个对象。它应该为空。

【讨论】:

    【解决方案7】:

    在 JavaScript 中,typeof null 是 'object',它错误地暗示 null 是一个对象。这是一个错误,很遗憾无法修复,因为它会破坏现有代码。

    【讨论】:

      【解决方案8】:

      对于那些对产生这种行为的代码感兴趣的人,这是给你们的链接......

      why typeof null is object with the implementation

      【讨论】:

        【解决方案9】:

        ECMAScript 规范标识了这些语言data types

        6.1.1 未定义类型
        6.1.2 Null 类型
        6.1.3 布尔类型
        6.1.4 字符串类型
        6.1.5 符号类型
        6.1.6 数值类型
        6.1.6.1 数字类型
        6.1.6.2 BigInt 类型
        6.1.7 对象类型

        由于历史原因,typeof 运算符在两种情况下与此分类不一致:

        • typeof null == "object":这很不幸,但我们必须忍受。
        • 函数对象的typeof 评估为“函数”,即使根据规范它具有数据类型 Object

        另一个操作符——instanceof——可以用来知道一个对象是否继承了某个原型。例如,[1,2] instanceof Array 将评估为 true。

        判断一个值是否为对象的一种方法是使用Object函数:

        if (Object(value) === value) // then it is an object; i.e., a non-primitive
        

        【讨论】:

          猜你喜欢
          • 2023-02-12
          • 1970-01-01
          • 2013-07-03
          • 1970-01-01
          • 2023-04-08
          • 1970-01-01
          • 2018-02-01
          • 2010-10-22
          相关资源
          最近更新 更多