扫码关注官方订阅号
感觉额外允许Object.prototype.__proto__ 为null没什么用啊,这么设计有什么原因么?
ringa_lee
首先要明确一点,原型链是指对象的原型链,所以原型链上的所有节点都是对象,不能是字符串、数字、布尔值等原始类型。
另外,规范要求原型链必须是有限长度的(从任一节点出发,经过有限步骤后必须到达一个终点。显然也不能有环。)
那么,应该用什么对象作为终点呢?很显然应该用一个特殊的对象。
好吧,Object.prototype确实是个特殊对象,我们先假设用它做终点。那么考虑一下,当你取它的原型时应该怎么办?即
Object.prototype
Object.prototype.__proto__;
应该返回什么?
取一个对象的属性时,可能发生三种情况:
如果属性存在,那么返回属性的值。
如果属性不存在,那么返回undefined。
不管属性存在还是不存在,有可能抛异常。
我们已经假设Object.prototype是终点了,所以看起来不能是情况1。另外,抛出异常也不是好的设计,所以也不是情况3。那么情况2呢,它不存在原型属性,返回undefined怎么样?也不好,因为返回undefined一种解释是原型不存在,但是也相当于原型就是undefined。这样,在原型链上就会存在一个非对象的值。
所以,最佳选择就是null。一方面,你没法访问null的属性,所以起到了终止原型链的作用;另一方面,null在某种意义上也是一种对象,即空对象,因为null一开始就是为表示一个“空”的对象存在的。这样一来,就不会违反“原型链上只能有对象”的约定。
所以,“原型链的终点是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 繼承 EngineerEngineer 繼承 WorkerBeeWorkerBee 繼承 EmployeeEmployee 繼承 ObjectObject 繼承誰? 他不繼承任何人,他本就實現 Object 的所有屬性方法,所以是 null,也讓 javascript 在追朔原型鏈時知道終點在哪。
cris
Engineer
WorkerBee
Employee
Object
null
javascript
原型鏈
存在的原因不是「有用」,而是「合乎理性」。
Object.prototype.__proto__ 如果不是 null 难道要是 undefined?
Object.prototype.__proto__
undefined
况且原型链是不能有环的(否则遍历原型链是不会有终点的),Object.prototype 是一切对象(除非手工设置 __proto__ 为 null)的原型,也就意味着它不能有任何对象作为原型。
__proto__
综上,Object.prototype.__proto__ 只能为 null,意为这里不该有值。
这一定义没有「用」,却对于 Javascript 的逻辑上完备而言是必须的。
object原型链终点为null为什么是nullnull表示没有对象
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
首先要明确一点,原型链是指对象的原型链,所以原型链上的所有节点都是对象,不能是字符串、数字、布尔值等原始类型。
另外,规范要求原型链必须是有限长度的(从任一节点出发,经过有限步骤后必须到达一个终点。显然也不能有环。)
那么,应该用什么对象作为终点呢?很显然应该用一个特殊的对象。
好吧,
Object.prototype确实是个特殊对象,我们先假设用它做终点。那么考虑一下,当你取它的原型时应该怎么办?即应该返回什么?
取一个对象的属性时,可能发生三种情况:
如果属性存在,那么返回属性的值。
如果属性不存在,那么返回undefined。
不管属性存在还是不存在,有可能抛异常。
我们已经假设
Object.prototype是终点了,所以看起来不能是情况1。另外,抛出异常也不是好的设计,所以也不是情况3。那么情况2呢,它不存在原型属性,返回undefined怎么样?也不好,因为返回undefined一种解释是原型不存在,但是也相当于原型就是undefined。这样,在原型链上就会存在一个非对象的值。所以,最佳选择就是null。一方面,你没法访问null的属性,所以起到了终止原型链的作用;另一方面,null在某种意义上也是一种对象,即空对象,因为null一开始就是为表示一个“空”的对象存在的。这样一来,就不会违反“原型链上只能有对象”的约定。
所以,“原型链的终点是null”虽然不是必须不可的,但是却是最合理的。
舉個例子 MDN
cris繼承EngineerEngineer繼承WorkerBeeWorkerBee繼承EmployeeEmployee繼承ObjectObject繼承誰? 他不繼承任何人,他本就實現Object的所有屬性方法,所以是null,也讓javascript在追朔原型鏈時知道終點在哪。存在的原因不是「有用」,而是「合乎理性」。
Object.prototype.__proto__如果不是null难道要是undefined?况且原型链是不能有环的(否则遍历原型链是不会有终点的),
Object.prototype是一切对象(除非手工设置__proto__为null)的原型,也就意味着它不能有任何对象作为原型。综上,
Object.prototype.__proto__只能为null,意为这里不该有值。这一定义没有「用」,却对于 Javascript 的逻辑上完备而言是必须的。
object原型链终点为null
为什么是null
null表示没有对象