我正在阅读“专业Web开发者Javascript”第4章,它告诉我五种类型的原语是:未定义,null,布尔,数字和字符串。
如果null是一个原语,为什么typeof(null)返回"object"?
null
typeof(null)
"object"
这是不是意味着null是通过引用传递的(我假设这里所有对象都是通过引用传递的),因此使它不是一个原语?
因为说明书是这么说的。
11.4.3 typeof操作符 产品UnaryExpression: typeof UnaryExpression的计算方法如下: 设瓦尔为UnaryExpression求值的结果。 如果类型(瓦尔)为参考,则 . > 真正的。如果IsUnresolvableReference (瓦尔),返回“undefined"。 b.设瓦尔为GetValue(瓦尔). 根据表20返回由类型(瓦尔)确定的String。
typeof
产品UnaryExpression: typeof UnaryExpression的计算方法如下:
undefined
从关于typeof操作符行为的MDN页面:
null // This stands since the beginning of JavaScript typeof null === 'object'; 在JavaScript的第一个实现中,JavaScript值被表示为一个类型标签和一个值。对象的类型标记为0。null表示为NULL指针(在大多数平台中为0x00)。因此,null的类型标记为0,因此"object" typeof返回值。(参考) 针对ECMAScript提出了一个修正(通过选择加入),但是被拒绝了. c。它的结果是typeof null === 'null'。
// This stands since the beginning of JavaScript typeof null === 'object';
在JavaScript的第一个实现中,JavaScript值被表示为一个类型标签和一个值。对象的类型标记为0。null表示为NULL指针(在大多数平台中为0x00)。因此,null的类型标记为0,因此"object" typeof返回值。(参考)
针对ECMAScript提出了一个修正(通过选择加入),但是被拒绝了. c。它的结果是typeof null === 'null'。
typeof null === 'null'
正如已经指出的,规范是这么说的。但是,由于JavaScript的实现早于ECMAScript规范的编写,并且该规范小心翼翼地没有纠正最初实现的缺点,因此仍然存在一个合理的问题,即为什么要以这种方式完成。Douglas Crockford;基罗风险我觉得这有点道理:
这背后的原因是,与undefined相比,null过去(现在仍然)经常在对象出现的地方使用。换句话说,null通常用于表示对对象的空引用。当Brendan Eich创建JavaScript时,他遵循了同样的范式,返回“object”是有意义的(可以说)。事实上,ECMAScript规范将null定义为表示有意缺少任何对象值的原语值 (ECMA-262, 11.4.11)。
object
简而言之:它是ECMAScript中的bug,类型应该是null
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null
从书YDKJS
这是JS中一个长期存在的错误,但可能永远不会消失 待修复。Web上有太多的代码依赖于这个bug,因此 修复它会导致更多的bug !< / p >
在JavaScript中,null是“nothing”。它应该是不存在的东西。不幸的是,在JavaScript中,null的数据类型是一个对象。你可以认为typeof null是一个对象是JavaScript的错误。它应该是空的。
在JavaScript中,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对象类型 . xml
由于历史原因,typeof操作符在以下两种情况下与此分类不一致:
typeof null == "object"
另一个操作符——instanceof——可以用来知道一个对象是否继承了某个原型。例如,[1,2] instanceof Array将计算为true。
instanceof
[1,2] instanceof Array
确定值是否为对象的一种方法是使用Object函数:
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第一版遗留下来的bug。
“这是一个错误,一个不幸的无法修复的错误,因为它会破坏现有的代码。”
更多信息请参考和:https://2ality.com/2013/10/typeof-null.html