所以我知道' null'是一种'对象'
然而,当我做Object.getProtoTypeOf(null)时,我收到一个错误。例如,同样的事情也是如此。
如果null是一种Object ...它应该在它的原型链中,对吧?
// 'object'
typeof null;
// gives error - Cannot convert undefined or null to object
Object.getPrototypeOf(null);
// false ---- why?
null instanceof Object
我有什么遗漏,或者JS太嬉皮了吗?!
答案 0 :(得分:3)
请参阅,null
不是对象。确实,typeof null
评估为'object'
,但它实际上来自一个限制,可能被认为是一种怪癖 - 在某种程度上是一个错误的JavaScript。引用this article:
“
typeof null
”错误是第一版的遗留物 JavaScript的。在此版本中,值以32位为单位存储 由一个小型标签(1-3位)和实际数据组成 值。类型标签存储在单元的低位中。那里 其中五个是:
- 000:
object
。数据是对象的引用。- 1:
int
。数据是31位有符号整数。- 010:
double
。数据是对双浮点数的引用。- 100:
string
。数据是对字符串的引用。- 110:
boolean
。数据是布尔值。也就是说,最低位是1,然后类型标签只有一位长。或者它为零,那么类型标签的长度为3位,提供两个 附加位,适用于四种类型。两个值很特别:
undefined
(JSVAL_VOID)是整数-2 30 (整数范围之外的数字)。null
(JSVAL_NULL)是机器代码的NULL指针。或者:对象类型标记加上引用为零。现在应该明白为什么typeof认为null是一个对象:它检查了它的类型标记,类型标记表示“对象”。
现在,对于其余操作null
被视为原始值。这就是为什么,例如,null instanceof Object
返回false - 任何原始的意志,因为它不能是一个实例。将42 instanceof Number
(false)与typeof 42 === 'number'
进行比较。
对于Object.getPrototypeOf(null)
,它有点不同。在ES5 standard中,如果函数的参数是基元 - 任何基元:
当使用参数
getPrototypeOf
调用O
函数时, 采取以下步骤:
- 如果
Type(O)
不是Object
则抛出TypeError
例外。- 返回
[[Prototype]]
的{{1}}内部属性的值。
然而,在ES2015中,他们changed it:
当使用参数
O
调用getPrototypeOf
函数时, 采取以下步骤:
- 让
O
成为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
方法(doc)抛出此异常 - 这是有道理的,因为无法“装箱”ToObject()
和null
。在某些方面,它与尝试访问undefined
或null
的属性时出现的错误类似。