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

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

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


当前回答

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

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值为"function",即使根据规范,它的数据类型为object。

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

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

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

其他回答

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

因为规范是这么说的。

11.4.3 typeof操作符 生成的UnaryExpression: typeof UnaryExpression的计算如下: 设val为对UnaryExpression求值的结果。 如果Type(val)是Reference,则 a.如果IsUnresolvableReference(val)为真,返回"undefined"。 b.设val为GetValue(val)。 返回一个由Type(val)根据表20确定的字符串。

这是javascript第一版遗留下来的bug。

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

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

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

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值为"function",即使根据规范,它的数据类型为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;
}

来自YDKJS这本书

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