说实话,很久没有关注原型
这个问题了,我对浏览器的__proto__
输出还停留在这个印象
直到有一天,输出对象
的时候,开始看新的[[Prototype]]
的时候,发现了一个问题,为什么[[Prototype]]
多套了一层:
思考
先简单回顾一下原型
:
构造函数
被new
调用的时候,prototype
属性会变成对象
的原型
,也就是说
function a(){}
let b = new a()
Object.getPrototypeOf(b) === a.prototype // true
- 访问对象的
原型
的标准方式
是使用Object.getPrototypeOf
,当然还有一种非标准
的访问方式,使用__proto__
ES6
增加了[[Prototype]]内部属性
来指向原型
,当然__proto__
现在为止还可以使用
其实一开始我把__proto__
和[[Prototype]]
看成是一样的,所以怎么也想不通,直到我想到实现
这两个字,才反应过来,[[Prototype]]
确实是标准
,但是__proto__
不是浏览器的自我实现
么,所以说,[[Prototype]]
上实现
了__proto__
。按照这种思路,我们再来看这多套一层就非常的合理。首先是按照__proto__
的方式访问,那就是这样:
let a = {}
a.__proto__.__proto__ === null // true
意思就是先访问[[Prototype]]
上的__proto__
,当然此时已经是Object.prototype
了,所以访问Object.prototype.__proto__
就是null
,这很符合原型
的设计,顶层为null
再按照[[Prototype]]
这个属性来访问原型
:
let a = {}
Object.getPrototypeOf(Object.getPrototypeOf(a)) === null //true
a
对象的原型
是Object.prototype
,但是Object.prototype
的[[Prototype]]
是不存在的,所以返回null