感觉额外允许Object.prototype.__proto__ 为null没什么用啊,这么设计有什么原因么?
舉個例子 MDN
chris.__proto__ == Engineer.prototype;
chris.__proto__.__proto__ == WorkerBee.prototype;
chris.__proto__.__proto__.__proto__ == Employee.prototype;
chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
cris
繼承 Engineer
Engineer
繼承 WorkerBee
WorkerBee
繼承 Employee
Employee
繼承 Object
Object
繼承誰? 他不繼承任何人,他本就實現 Object
的所有屬性方法,所以是 null
,也讓 javascript
在追朔原型鏈
時知道終點在哪。
存在的原因不是「有用」,而是「合乎理性」。
Object.prototype.__proto__
如果不是 null
难道要是 undefined
?
况且原型链是不能有环的(否则遍历原型链是不会有终点的),Object.prototype
是一切对象(除非手工设置 __proto__
为 null
)的原型,也就意味着它不能有任何对象作为原型。
综上,Object.prototype.__proto__
只能为 null
,意为这里不该有值。
这一定义没有「用」,却对于 Javascript 的逻辑上完备而言是必须的。
8 回答5k 阅读✓ 已解决
6 回答3.7k 阅读✓ 已解决
5 回答3k 阅读✓ 已解决
6 回答2.6k 阅读
9 回答2.1k 阅读
5 回答6.6k 阅读✓ 已解决
4 回答2.4k 阅读✓ 已解决
首先要明确一点,原型链是指对象的原型链,所以原型链上的所有节点都是对象,不能是字符串、数字、布尔值等原始类型。
另外,规范要求原型链必须是有限长度的(从任一节点出发,经过有限步骤后必须到达一个终点。显然也不能有环。)
那么,应该用什么对象作为终点呢?很显然应该用一个特殊的对象。
好吧,
Object.prototype
确实是个特殊对象,我们先假设用它做终点。那么考虑一下,当你取它的原型时应该怎么办?即应该返回什么?
取一个对象的属性时,可能发生三种情况:
如果属性存在,那么返回属性的值。
如果属性不存在,那么返回undefined。
不管属性存在还是不存在,有可能抛异常。
我们已经假设
Object.prototype
是终点了,所以看起来不能是情况1。另外,抛出异常也不是好的设计,所以也不是情况3。那么情况2呢,它不存在原型属性,返回undefined怎么样?也不好,因为返回undefined一种解释是原型不存在,但是也相当于原型就是undefined。这样,在原型链上就会存在一个非对象的值。所以,最佳选择就是null。一方面,你没法访问null的属性,所以起到了终止原型链的作用;另一方面,null在某种意义上也是一种对象,即空对象,因为null一开始就是为表示一个“空”的对象存在的。这样一来,就不会违反“原型链上只能有对象”的约定。
所以,“原型链的终点是null”虽然不是必须不可的,但是却是最合理的。