所以我知道'null'是一种'对象'
但是,当我执行Object.getProtoTypeOf(null)时,我收到一个错误。例如,这同样是一回事。
如果 null 是对象类型...它应该在它的原型链中,对吧?
// 'object'
typeof null;
// gives error - Cannot convert undefined or null to object
Object.getPrototypeOf(null);
// false ---- why?
null instanceof Object
是不是我错过了什么,或者JS太嬉皮了?!
看,null
不是一个对象。的确,typeof null
的计算结果是'object'
,但它实际上来自一个限制,可能被认为是JavaScript的一个怪癖 - 在某种程度上是一个错误。引用这篇文章:
"
typeof null
"错误是第一个版本的残余 JavaScript。在此版本中,值以 32 位为单位存储,其中 由一个小类型标签(1-3位)和 价值。类型标签存储在单元的下部位。那里 是其中的五个:
- 000:
object
.数据是对对象的引用。- 1:
int
。数据是 31 位有符号整数。- 010:
double
.数据是对双精度浮点数的引用。- 100:
string
。数据是对字符串的引用。- 110:
boolean
.数据是布尔值。也就是说,最低位是任一位,然后类型标记只有一位长。或者为零,则类型标签的长度为三位,提供两个 附加位,用于四种类型。有两个值很特别:
undefined
(JSVAL_VOID) 是整数 −230(整数范围之外的数字)。null
(JSVAL_NULL) 是机器代码 NULL 指针。或者:对象类型标记加上零引用。现在应该很清楚为什么typeof认为null是一个对象:它检查了它的类型标签,类型标签说"对象"。
现在,对于其余操作,null
被视为基元值。这就是为什么,例如,null instanceof Object
返回 false - 任何原始意志,因为它不能是一个实例。将42 instanceof Number
(假)与typeof 42 === 'number'
进行比较。
对于Object.getPrototypeOf(null)
来说,这有点不同。在 ES5 标准中,如果此函数的参数是原语 - 任何原语,则应抛出异常:
当使用参数
O
调用getPrototypeOf
函数时, 将采取以下步骤:
- 如果不是
Type(O)
Object
则引发TypeError
异常。- 返回
O
的[[Prototype]]
内部属性的值。
但是,在ES2015中,他们对其进行了更改:
当使用参数
O
调用getPrototypeOf
函数时, 将采取以下步骤:
obj
ToObject(O)
.ReturnIfAbrupt(obj)
.- 返回
obj.[[GetPrototypeOf]]()
.
。所以Object.getPrototypeOf(42)
现在有效。然而,Object.getPrototypeOf(undefined)
和Object.getPrototypeOf(null)
都抛出了相同的错误:
Uncaught TypeError: Cannot convert undefined or null to object
此异常由ToObject()
方法(doc)引发 - 这是有道理的,因为不能"框"null
和undefined
。在某些方面,它类似于您尝试访问null
或undefined
的属性时遇到的错误。