311

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

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

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

4

9 回答 9

262

MDN 页面关于typeof操作员的行为:

null

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

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

提出了针对 ECMAScript 的修复(通过选择加入),但被拒绝了。它会导致typeof null === 'null'.

于 2013-09-15T02:10:36.377 回答
75

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

因为规范是这么说的

11.4.3运营typeof

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

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

在此处输入图像描述

于 2013-09-15T02:07:25.923 回答
32

正如已经指出的那样,规范是这样说的。但是由于 JavaScript 的实现早于 ECMAScript 规范的编写,并且规范小心翼翼地不纠正初始实现的弱点,所以仍然存在一个合理的问题,即为什么它首先会以这种方式完成。道格拉斯·克罗克福德称这是一个错误。Kiro Risk认为这有点道理

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

于 2013-09-15T02:16:49.037 回答
9

From the book YDKJS

This is a long-standing bug in JS, but one that is likely never going to be fixed. Too much code on the Web relies on the bug and thus fixing it would cause a lot more bugs!

于 2016-10-26T06:19:35.667 回答
5

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

简而言之:它是 ECMAScript 中的错误,类型应该是null

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

于 2015-05-06T10:37:27.693 回答
2

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

于 2019-12-20T11:46:09.450 回答
0

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

于 2020-03-10T21:02:40.120 回答
0

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

为什么 typeof null 是具有实现的对象

于 2020-05-20T21:30:49.450 回答
0

ECMAScript 规范标识了这些语言数据类型

6.1.1 未定义类型
6.1.2 Null 类型
6.1.3 Boolean 类型
6.1.4 String 类型
6.1.5 Symbol 类型
6.1.6 Numeric 类型
    6.1.6.1 Number 类型
    6.1.6.2 BigInt 类型
6.1.7对象类型

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

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

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

确定值是否为对象的一种方法是使用Object函数:

if (Object(value) === value) // then it is an object; i.e., a non-primitive
于 2021-09-02T10:51:00.930 回答