繁体   English   中英

为什么typeof null“对象”?

[英]Why is typeof null "object"?

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

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

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

MDN 页面关于typeof运算符的行为

null

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

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

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

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

因为规范是这么说的

11.4.3 typeof运算符

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

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

在此处输入图像描述

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

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

从书YDKJS

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

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

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

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

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

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

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

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

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

6.1.1 未定义类型
6.1.2 空类型
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

++作者的回答是:

我认为修复 typeof 为时已晚。 对 typeof null 提出的更改将破坏现有代码

太晚了。 自从微软创建了自己的 JavaScript 引擎并复制了第一个引擎版本的所有功能和错误之后,所有后续引擎都复制了这个错误,现在修复它已经太晚了。

JS_TypeOfValue(JSContext *cx, jsval v)
{
    JSType type = JSTYPE_VOID;
    JSObject *obj;
    JSObjectOps *ops;
    JSClass *clasp;

    CHECK_REQUEST(cx);
    if (JSVAL_IS_VOID(v)) {
        type = JSTYPE_VOID;
    } else if (JSVAL_IS_OBJECT(v)) {
        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;
}

这是 javascript 的第一个版本遗留的错误。

“这是一个错误,不幸的是无法修复,因为它会破坏现有代码。”

参考和更多信息: https ://2ality.com/2013/10/typeof-null.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM